hughesjr / rpms / docker

Forked from rpms/docker 4 years ago
Clone
Blob Blame History Raw
From 4e3b8e37a34c9b6678320e6fcdad686fb481a58f Mon Sep 17 00:00:00 2001
From: Lokesh Mandvekar <lsm5@fedoraproject.org>
Date: Thu, 30 Apr 2015 10:35:34 -0400
Subject: [PATCH] include updated go-md2man and deps

Signed-off-by: Lokesh Mandvekar <lsm5@fedoraproject.org>
---
 .../src/github.com/cpuguy83/go-md2man/LICENSE.md   |   21 +
 vendor/src/github.com/cpuguy83/go-md2man/README.md |   11 +
 .../github.com/cpuguy83/go-md2man/go-md2man.1.md   |   21 +
 .../github.com/cpuguy83/go-md2man/mangen/mangen.go |  272 ++++
 vendor/src/github.com/cpuguy83/go-md2man/md2man.go |   55 +
 .../github.com/russross/blackfriday/.travis.yml    |   17 +
 .../github.com/russross/blackfriday/LICENSE.txt    |   29 +
 .../src/github.com/russross/blackfriday/README.md  |  246 ++++
 .../src/github.com/russross/blackfriday/block.go   | 1339 ++++++++++++++++++++
 .../github.com/russross/blackfriday/block_test.go  | 1296 +++++++++++++++++++
 vendor/src/github.com/russross/blackfriday/html.go |  922 ++++++++++++++
 .../src/github.com/russross/blackfriday/inline.go  | 1096 ++++++++++++++++
 .../github.com/russross/blackfriday/inline_test.go |  958 ++++++++++++++
 .../src/github.com/russross/blackfriday/latex.go   |  332 +++++
 .../github.com/russross/blackfriday/markdown.go    |  838 ++++++++++++
 .../github.com/russross/blackfriday/ref_test.go    |  128 ++
 .../github.com/russross/blackfriday/smartypants.go |  398 ++++++
 .../testdata/Amps and angle encoding.html          |   17 +
 .../testdata/Amps and angle encoding.text          |   21 +
 .../russross/blackfriday/testdata/Auto links.html  |   18 +
 .../russross/blackfriday/testdata/Auto links.text  |   13 +
 .../blackfriday/testdata/Backslash escapes.html    |  123 ++
 .../blackfriday/testdata/Backslash escapes.text    |  126 ++
 .../testdata/Blockquotes with code blocks.html     |   15 +
 .../testdata/Blockquotes with code blocks.text     |   11 +
 .../russross/blackfriday/testdata/Code Blocks.html |   18 +
 .../russross/blackfriday/testdata/Code Blocks.text |   14 +
 .../russross/blackfriday/testdata/Code Spans.html  |    5 +
 .../russross/blackfriday/testdata/Code Spans.text  |    6 +
 ...list-like lines no empty line before block.html |   14 +
 ...list-like lines no empty line before block.text |    8 +
 ...rd-wrapped paragraphs with list-like lines.html |    8 +
 ...rd-wrapped paragraphs with list-like lines.text |    8 +
 .../blackfriday/testdata/Horizontal rules.html     |   71 ++
 .../blackfriday/testdata/Horizontal rules.text     |   67 +
 .../testdata/Inline HTML (Advanced).html           |   15 +
 .../testdata/Inline HTML (Advanced).text           |   15 +
 .../blackfriday/testdata/Inline HTML (Simple).html |   72 ++
 .../blackfriday/testdata/Inline HTML (Simple).text |   69 +
 .../blackfriday/testdata/Inline HTML comments.html |   13 +
 .../blackfriday/testdata/Inline HTML comments.text |   13 +
 .../blackfriday/testdata/Links, inline style.html  |   11 +
 .../blackfriday/testdata/Links, inline style.text  |   12 +
 .../testdata/Links, reference style.html           |   52 +
 .../testdata/Links, reference style.text           |   71 ++
 .../testdata/Links, shortcut references.html       |    9 +
 .../testdata/Links, shortcut references.text       |   20 +
 .../testdata/Literal quotes in titles.html         |    3 +
 .../testdata/Literal quotes in titles.text         |    7 +
 .../testdata/Markdown Documentation - Basics.html  |  314 +++++
 .../testdata/Markdown Documentation - Basics.text  |  306 +++++
 .../testdata/Markdown Documentation - Syntax.html  |  946 ++++++++++++++
 .../testdata/Markdown Documentation - Syntax.text  |  888 +++++++++++++
 .../blackfriday/testdata/Nested blockquotes.html   |    9 +
 .../blackfriday/testdata/Nested blockquotes.text   |    5 +
 .../testdata/Ordered and unordered lists.html      |  166 +++
 .../testdata/Ordered and unordered lists.text      |  131 ++
 .../testdata/Strong and em together.html           |    7 +
 .../testdata/Strong and em together.text           |    7 +
 .../russross/blackfriday/testdata/Tabs.html        |   26 +
 .../russross/blackfriday/testdata/Tabs.text        |   21 +
 .../russross/blackfriday/testdata/Tidyness.html    |    9 +
 .../russross/blackfriday/testdata/Tidyness.text    |    5 +
 .../shurcooL/sanitized_anchor_name/.travis.yml     |   10 +
 .../shurcooL/sanitized_anchor_name/README.md       |   25 +
 .../shurcooL/sanitized_anchor_name/main.go         |   29 +
 .../shurcooL/sanitized_anchor_name/main_test.go    |   35 +
 67 files changed, 11863 insertions(+)
 create mode 100644 vendor/src/github.com/cpuguy83/go-md2man/LICENSE.md
 create mode 100644 vendor/src/github.com/cpuguy83/go-md2man/README.md
 create mode 100644 vendor/src/github.com/cpuguy83/go-md2man/go-md2man.1.md
 create mode 100644 vendor/src/github.com/cpuguy83/go-md2man/mangen/mangen.go
 create mode 100644 vendor/src/github.com/cpuguy83/go-md2man/md2man.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/.travis.yml
 create mode 100644 vendor/src/github.com/russross/blackfriday/LICENSE.txt
 create mode 100644 vendor/src/github.com/russross/blackfriday/README.md
 create mode 100644 vendor/src/github.com/russross/blackfriday/block.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/block_test.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/html.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/inline.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/inline_test.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/latex.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/markdown.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/ref_test.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/smartypants.go
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Auto links.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Auto links.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Code Spans.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Code Spans.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Tabs.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Tabs.text
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Tidyness.html
 create mode 100644 vendor/src/github.com/russross/blackfriday/testdata/Tidyness.text
 create mode 100644 vendor/src/github.com/shurcooL/sanitized_anchor_name/.travis.yml
 create mode 100644 vendor/src/github.com/shurcooL/sanitized_anchor_name/README.md
 create mode 100644 vendor/src/github.com/shurcooL/sanitized_anchor_name/main.go
 create mode 100644 vendor/src/github.com/shurcooL/sanitized_anchor_name/main_test.go

diff --git a/vendor/src/github.com/cpuguy83/go-md2man/LICENSE.md b/vendor/src/github.com/cpuguy83/go-md2man/LICENSE.md
new file mode 100644
index 0000000..1cade6c
--- /dev/null
+++ b/vendor/src/github.com/cpuguy83/go-md2man/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Brian Goff
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/vendor/src/github.com/cpuguy83/go-md2man/README.md b/vendor/src/github.com/cpuguy83/go-md2man/README.md
new file mode 100644
index 0000000..8eb4b2e
--- /dev/null
+++ b/vendor/src/github.com/cpuguy83/go-md2man/README.md
@@ -0,0 +1,11 @@
+go-md2man
+=========
+
+** Work in Progress **
+This still needs a lot of help to be complete, or even usable!
+
+Uses blackfriday to process markdown into man pages.
+
+### Usage
+
+./md2man -in /path/to/markdownfile.md -out /manfile/output/path
diff --git a/vendor/src/github.com/cpuguy83/go-md2man/go-md2man.1.md b/vendor/src/github.com/cpuguy83/go-md2man/go-md2man.1.md
new file mode 100644
index 0000000..1f7096a
--- /dev/null
+++ b/vendor/src/github.com/cpuguy83/go-md2man/go-md2man.1.md
@@ -0,0 +1,21 @@
+go-md2man 1 "January 2015" go-md2man "User Manual"
+==================================================
+
+# NAME
+  go-md2man - Convert mardown files into manpages
+
+# SYNOPSIS
+  go-md2man -in=[/path/to/md/file] -out=[/path/to/output]
+
+# Description
+  go-md2man converts standard markdown formatted documents into manpages. It is
+  written purely in Go so as to reduce dependencies on 3rd party libs.
+
+# Example
+  Convert the markdown file "go-md2man.1.md" into a manpage.
+
+    go-md2man -in=README.md -out=go-md2man.1.out
+
+# HISTORY
+  January 2015, Originally compiled by Brian Goff( cpuguy83@gmail.com )
+
diff --git a/vendor/src/github.com/cpuguy83/go-md2man/mangen/mangen.go b/vendor/src/github.com/cpuguy83/go-md2man/mangen/mangen.go
new file mode 100644
index 0000000..d436eed
--- /dev/null
+++ b/vendor/src/github.com/cpuguy83/go-md2man/mangen/mangen.go
@@ -0,0 +1,272 @@
+package mangen
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+
+	"github.com/russross/blackfriday"
+)
+
+type Man struct{}
+
+func ManRenderer(flags int) blackfriday.Renderer {
+	return &Man{}
+}
+
+func (m *Man) GetFlags() int {
+	return 0
+}
+
+func (m *Man) TitleBlock(out *bytes.Buffer, text []byte) {
+	out.WriteString(".TH ")
+
+	splitText := bytes.Split(text, []byte("\n"))
+	for i, line := range splitText {
+		line = bytes.TrimPrefix(line, []byte("% "))
+		if i == 0 {
+			line = bytes.Replace(line, []byte("("), []byte("\" \""), 1)
+			line = bytes.Replace(line, []byte(")"), []byte("\" \""), 1)
+		}
+		line = append([]byte("\""), line...)
+		line = append(line, []byte("\" ")...)
+		out.Write(line)
+	}
+
+	out.WriteString(" \"\"\n")
+}
+
+func (m *Man) BlockCode(out *bytes.Buffer, text []byte, lang string) {
+	out.WriteString("\n.PP\n.RS\n\n.nf\n")
+	escapeSpecialChars(out, text)
+	out.WriteString("\n.fi\n.RE\n")
+}
+
+func (m *Man) BlockQuote(out *bytes.Buffer, text []byte) {
+	out.WriteString("\n.PP\n.RS\n")
+	out.Write(text)
+	out.WriteString("\n.RE\n")
+}
+
+func (m *Man) BlockHtml(out *bytes.Buffer, text []byte) {
+	fmt.Errorf("man: BlockHtml not supported")
+	out.Write(text)
+}
+
+func (m *Man) Header(out *bytes.Buffer, text func() bool, level int, id string) {
+	marker := out.Len()
+
+	switch {
+	case marker == 0:
+		// This is the doc header
+		out.WriteString(".TH ")
+	case level == 1:
+		out.WriteString("\n\n.SH ")
+	case level == 2:
+		out.WriteString("\n.SH ")
+	default:
+		out.WriteString("\n.SS ")
+	}
+
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+}
+
+func (m *Man) HRule(out *bytes.Buffer) {
+	out.WriteString("\n.ti 0\n\\l'\\n(.lu'\n")
+}
+
+func (m *Man) List(out *bytes.Buffer, text func() bool, flags int) {
+	marker := out.Len()
+	out.WriteString(".IP ")
+	if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
+		out.WriteString("\\(bu 2")
+	} else {
+		out.WriteString("\\n+[step" + string(flags) + "]")
+	}
+	out.WriteString("\n")
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+
+}
+
+func (m *Man) ListItem(out *bytes.Buffer, text []byte, flags int) {
+	out.WriteString("\n\\item ")
+	out.Write(text)
+}
+
+func (m *Man) Paragraph(out *bytes.Buffer, text func() bool) {
+	marker := out.Len()
+	out.WriteString("\n.PP\n")
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	if marker != 0 {
+		out.WriteString("\n")
+	}
+}
+
+// TODO: This might now work
+func (m *Man) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
+	out.WriteString(".TS\nallbox;\n")
+
+	out.Write(header)
+	out.Write(body)
+	out.WriteString("\n.TE\n")
+}
+
+func (m *Man) TableRow(out *bytes.Buffer, text []byte) {
+	if out.Len() > 0 {
+		out.WriteString("\n")
+	}
+	out.Write(text)
+	out.WriteString("\n")
+}
+
+func (m *Man) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
+	if out.Len() > 0 {
+		out.WriteString(" ")
+	}
+	out.Write(text)
+	out.WriteString(" ")
+}
+
+// TODO: This is probably broken
+func (m *Man) TableCell(out *bytes.Buffer, text []byte, align int) {
+	if out.Len() > 0 {
+		out.WriteString("\t")
+	}
+	out.Write(text)
+	out.WriteString("\t")
+}
+
+func (m *Man) Footnotes(out *bytes.Buffer, text func() bool) {
+
+}
+
+func (m *Man) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
+
+}
+
+func (m *Man) AutoLink(out *bytes.Buffer, link []byte, kind int) {
+	out.WriteString("\n\\[la]")
+	out.Write(link)
+	out.WriteString("\\[ra]")
+}
+
+func (m *Man) CodeSpan(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\fB\\fC")
+	escapeSpecialChars(out, text)
+	out.WriteString("\\fR")
+}
+
+func (m *Man) DoubleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\fB")
+	out.Write(text)
+	out.WriteString("\\fP")
+}
+
+func (m *Man) Emphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\fI")
+	out.Write(text)
+	out.WriteString("\\fP")
+}
+
+func (m *Man) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
+	fmt.Errorf("man: Image not supported")
+}
+
+func (m *Man) LineBreak(out *bytes.Buffer) {
+	out.WriteString("\n.br\n")
+}
+
+func (m *Man) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
+	m.AutoLink(out, link, 0)
+}
+
+func (m *Man) RawHtmlTag(out *bytes.Buffer, tag []byte) {
+	out.Write(tag)
+}
+
+func (m *Man) TripleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\s+2")
+	out.Write(text)
+	out.WriteString("\\s-2")
+}
+
+func (m *Man) StrikeThrough(out *bytes.Buffer, text []byte) {
+	fmt.Errorf("man: strikethrough not supported")
+}
+
+func (m *Man) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
+
+}
+
+func (m *Man) Entity(out *bytes.Buffer, entity []byte) {
+	// TODO: convert this into a unicode character or something
+	out.Write(entity)
+}
+
+func processFooterText(text []byte) []byte {
+	text = bytes.TrimPrefix(text, []byte("% "))
+	newText := []byte{}
+	textArr := strings.Split(string(text), ") ")
+
+	for i, w := range textArr {
+		if i == 0 {
+			w = strings.Replace(w, "(", "\" \"", 1)
+			w = fmt.Sprintf("\"%s\"", w)
+		} else {
+			w = fmt.Sprintf(" \"%s\"", w)
+		}
+		newText = append(newText, []byte(w)...)
+	}
+	newText = append(newText, []byte(" \"\"")...)
+
+	return newText
+}
+
+func (m *Man) NormalText(out *bytes.Buffer, text []byte) {
+	escapeSpecialChars(out, text)
+}
+
+func (m *Man) DocumentHeader(out *bytes.Buffer) {
+}
+
+func (m *Man) DocumentFooter(out *bytes.Buffer) {
+}
+
+func needsBackslash(c byte) bool {
+	for _, r := range []byte("-_{}&\\~") {
+		if c == r {
+			return true
+		}
+	}
+	return false
+}
+
+func escapeSpecialChars(out *bytes.Buffer, text []byte) {
+	for i := 0; i < len(text); i++ {
+		// directly copy normal characters
+		org := i
+
+		for i < len(text) && !needsBackslash(text[i]) {
+			i++
+		}
+		if i > org {
+			out.Write(text[org:i])
+		}
+
+		// escape a character
+		if i >= len(text) {
+			break
+		}
+		out.WriteByte('\\')
+		out.WriteByte(text[i])
+	}
+}
diff --git a/vendor/src/github.com/cpuguy83/go-md2man/md2man.go b/vendor/src/github.com/cpuguy83/go-md2man/md2man.go
new file mode 100644
index 0000000..f8b1722
--- /dev/null
+++ b/vendor/src/github.com/cpuguy83/go-md2man/md2man.go
@@ -0,0 +1,55 @@
+package main
+
+import (
+	"flag"
+	"fmt"
+	"io/ioutil"
+	"os"
+
+	"github.com/cpuguy83/go-md2man/mangen"
+	"github.com/russross/blackfriday"
+)
+
+var inFilePath = flag.String("in", "", "Path to file to be processed")
+var outFilePath = flag.String("out", "", "Path to output processed file")
+
+func main() {
+	flag.Parse()
+
+	inFile, err := os.Open(*inFilePath)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+	defer inFile.Close()
+
+	doc, err := ioutil.ReadAll(inFile)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+
+	renderer := mangen.ManRenderer(0)
+	extensions := 0
+	extensions |= blackfriday.EXTENSION_NO_INTRA_EMPHASIS
+	extensions |= blackfriday.EXTENSION_TABLES
+	extensions |= blackfriday.EXTENSION_FENCED_CODE
+	extensions |= blackfriday.EXTENSION_AUTOLINK
+	extensions |= blackfriday.EXTENSION_SPACE_HEADERS
+	extensions |= blackfriday.EXTENSION_FOOTNOTES
+	extensions |= blackfriday.EXTENSION_TITLEBLOCK
+
+	out := blackfriday.Markdown(doc, renderer, extensions)
+
+	outFile, err := os.Create(*outFilePath)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+	defer outFile.Close()
+	_, err = outFile.Write(out)
+	if err != nil {
+		fmt.Println(err)
+		os.Exit(1)
+	}
+}
diff --git a/vendor/src/github.com/russross/blackfriday/.travis.yml b/vendor/src/github.com/russross/blackfriday/.travis.yml
new file mode 100644
index 0000000..4dd7a1c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/.travis.yml
@@ -0,0 +1,17 @@
+# Travis CI (http://travis-ci.org/) is a continuous integration service for
+# open source projects. This file configures it to run unit tests for
+# blackfriday.
+
+language: go
+
+go:
+    - 1.2
+    - 1.3
+    - 1.4
+
+install:
+    - go get -d -t -v ./...
+    - go build -v ./...
+
+script:
+    - go test -v ./...
diff --git a/vendor/src/github.com/russross/blackfriday/LICENSE.txt b/vendor/src/github.com/russross/blackfriday/LICENSE.txt
new file mode 100644
index 0000000..2885af3
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/LICENSE.txt
@@ -0,0 +1,29 @@
+Blackfriday is distributed under the Simplified BSD License:
+
+> Copyright © 2011 Russ Ross
+> All rights reserved.
+>
+> Redistribution and use in source and binary forms, with or without
+> modification, are permitted provided that the following conditions
+> are met:
+>
+> 1.  Redistributions of source code must retain the above copyright
+>     notice, this list of conditions and the following disclaimer.
+>
+> 2.  Redistributions in binary form must reproduce the above
+>     copyright notice, this list of conditions and the following
+>     disclaimer in the documentation and/or other materials provided with
+>     the distribution.
+>
+> THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+> "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+> LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+> FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+> COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+> INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+> BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+> LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+> CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+> LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+> ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+> POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/src/github.com/russross/blackfriday/README.md b/vendor/src/github.com/russross/blackfriday/README.md
new file mode 100644
index 0000000..1bb985d
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/README.md
@@ -0,0 +1,246 @@
+Blackfriday [![Build Status](https://travis-ci.org/russross/blackfriday.svg?branch=master)](https://travis-ci.org/russross/blackfriday)
+===========
+
+Blackfriday is a [Markdown][1] processor implemented in [Go][2]. It
+is paranoid about its input (so you can safely feed it user-supplied
+data), it is fast, it supports common extensions (tables, smart
+punctuation substitutions, etc.), and it is safe for all utf-8
+(unicode) input.
+
+HTML output is currently supported, along with Smartypants
+extensions. An experimental LaTeX output engine is also included.
+
+It started as a translation from C of [Sundown][3].
+
+
+Installation
+------------
+
+Blackfriday is compatible with Go 1. If you are using an older
+release of Go, consider using v1.1 of blackfriday, which was based
+on the last stable release of Go prior to Go 1. You can find it as a
+tagged commit on github.
+
+With Go 1 and git installed:
+
+    go get github.com/russross/blackfriday
+
+will download, compile, and install the package into your `$GOPATH`
+directory hierarchy. Alternatively, you can achieve the same if you
+import it into a project:
+
+    import "github.com/russross/blackfriday"
+
+and `go get` without parameters.
+
+Usage
+-----
+
+For basic usage, it is as simple as getting your input into a byte
+slice and calling:
+
+    output := blackfriday.MarkdownBasic(input)
+
+This renders it with no extensions enabled. To get a more useful
+feature set, use this instead:
+
+    output := blackfriday.MarkdownCommon(input)
+
+### Sanitize untrusted content
+
+Blackfriday itself does nothing to protect against malicious content. If you are
+dealing with user-supplied markdown, we recommend running blackfriday's output
+through HTML sanitizer such as
+[Bluemonday](https://github.com/microcosm-cc/bluemonday).
+
+Here's an example of simple usage of blackfriday together with bluemonday:
+
+``` go
+import (
+    "github.com/microcosm-cc/bluemonday"
+    "github.com/russross/blackfriday"
+)
+
+// ...
+unsafe := blackfriday.MarkdownCommon(input)
+html := bluemonday.UGCPolicy().SanitizeBytes(unsafe)
+```
+
+### Custom options
+
+If you want to customize the set of options, first get a renderer
+(currently either the HTML or LaTeX output engines), then use it to
+call the more general `Markdown` function. For examples, see the
+implementations of `MarkdownBasic` and `MarkdownCommon` in
+`markdown.go`.
+
+You can also check out `blackfriday-tool` for a more complete example
+of how to use it. Download and install it using:
+
+    go get github.com/russross/blackfriday-tool
+
+This is a simple command-line tool that allows you to process a
+markdown file using a standalone program.  You can also browse the
+source directly on github if you are just looking for some example
+code:
+
+* <http://github.com/russross/blackfriday-tool>
+
+Note that if you have not already done so, installing
+`blackfriday-tool` will be sufficient to download and install
+blackfriday in addition to the tool itself. The tool binary will be
+installed in `$GOPATH/bin`.  This is a statically-linked binary that
+can be copied to wherever you need it without worrying about
+dependencies and library versions.
+
+
+Features
+--------
+
+All features of Sundown are supported, including:
+
+*   **Compatibility**. The Markdown v1.0.3 test suite passes with
+    the `--tidy` option.  Without `--tidy`, the differences are
+    mostly in whitespace and entity escaping, where blackfriday is
+    more consistent and cleaner.
+
+*   **Common extensions**, including table support, fenced code
+    blocks, autolinks, strikethroughs, non-strict emphasis, etc.
+
+*   **Safety**. Blackfriday is paranoid when parsing, making it safe
+    to feed untrusted user input without fear of bad things
+    happening. The test suite stress tests this and there are no
+    known inputs that make it crash.  If you find one, please let me
+    know and send me the input that does it.
+
+    NOTE: "safety" in this context means *runtime safety only*. In order to
+    protect yourself agains JavaScript injection in untrusted content, see
+    [this example](https://github.com/russross/blackfriday#sanitize-untrusted-content).
+
+*   **Fast processing**. It is fast enough to render on-demand in
+    most web applications without having to cache the output.
+
+*   **Thread safety**. You can run multiple parsers in different
+    goroutines without ill effect. There is no dependence on global
+    shared state.
+
+*   **Minimal dependencies**. Blackfriday only depends on standard
+    library packages in Go. The source code is pretty
+    self-contained, so it is easy to add to any project, including
+    Google App Engine projects.
+
+*   **Standards compliant**. Output successfully validates using the
+    W3C validation tool for HTML 4.01 and XHTML 1.0 Transitional.
+
+
+Extensions
+----------
+
+In addition to the standard markdown syntax, this package
+implements the following extensions:
+
+*   **Intra-word emphasis supression**. The `_` character is
+    commonly used inside words when discussing code, so having
+    markdown interpret it as an emphasis command is usually the
+    wrong thing. Blackfriday lets you treat all emphasis markers as
+    normal characters when they occur inside a word.
+
+*   **Tables**. Tables can be created by drawing them in the input
+    using a simple syntax:
+
+    ```
+    Name    | Age
+    --------|------
+    Bob     | 27
+    Alice   | 23
+    ```
+
+*   **Fenced code blocks**. In addition to the normal 4-space
+    indentation to mark code blocks, you can explicitly mark them
+    and supply a language (to make syntax highlighting simple). Just
+    mark it like this:
+
+        ``` go
+        func getTrue() bool {
+            return true
+        }
+        ```
+
+    You can use 3 or more backticks to mark the beginning of the
+    block, and the same number to mark the end of the block.
+
+*   **Autolinking**. Blackfriday can find URLs that have not been
+    explicitly marked as links and turn them into links.
+
+*   **Strikethrough**. Use two tildes (`~~`) to mark text that
+    should be crossed out.
+
+*   **Hard line breaks**. With this extension enabled (it is off by
+    default in the `MarkdownBasic` and `MarkdownCommon` convenience
+    functions), newlines in the input translate into line breaks in
+    the output.
+
+*   **Smart quotes**. Smartypants-style punctuation substitution is
+    supported, turning normal double- and single-quote marks into
+    curly quotes, etc.
+
+*   **LaTeX-style dash parsing** is an additional option, where `--`
+    is translated into `&ndash;`, and `---` is translated into
+    `&mdash;`. This differs from most smartypants processors, which
+    turn a single hyphen into an ndash and a double hyphen into an
+    mdash.
+
+*   **Smart fractions**, where anything that looks like a fraction
+    is translated into suitable HTML (instead of just a few special
+    cases like most smartypant processors). For example, `4/5`
+    becomes `<sup>4</sup>&frasl;<sub>5</sub>`, which renders as
+    <sup>4</sup>&frasl;<sub>5</sub>.
+
+
+Other renderers
+---------------
+
+Blackfriday is structured to allow alternative rendering engines. Here
+are a few of note:
+
+*   [github_flavored_markdown](https://godoc.org/github.com/shurcooL/go/github_flavored_markdown):
+    provides a GitHub Flavored Markdown renderer with fenced code block
+    highlighting, clickable header anchor links.
+
+    It's not customizable, and its goal is to produce HTML output
+    equivalent to the [GitHub Markdown API endpoint](https://developer.github.com/v3/markdown/#render-a-markdown-document-in-raw-mode),
+    except the rendering is performed locally.
+
+*   [markdownfmt](https://github.com/shurcooL/markdownfmt): like gofmt,
+    but for markdown.
+
+*   LaTeX output: renders output as LaTeX. This is currently part of the
+    main Blackfriday repository, but may be split into its own project
+    in the future. If you are interested in owning and maintaining the
+    LaTeX output component, please be in touch.
+
+    It renders some basic documents, but is only experimental at this
+    point. In particular, it does not do any inline escaping, so input
+    that happens to look like LaTeX code will be passed through without
+    modification.
+
+
+Todo
+----
+
+*   More unit testing
+*   Improve unicode support. It does not understand all unicode
+    rules (about what constitutes a letter, a punctuation symbol,
+    etc.), so it may fail to detect word boundaries correctly in
+    some instances. It is safe on all utf-8 input.
+
+
+License
+-------
+
+[Blackfriday is distributed under the Simplified BSD License](LICENSE.txt)
+
+
+   [1]: http://daringfireball.net/projects/markdown/ "Markdown"
+   [2]: http://golang.org/ "Go Language"
+   [3]: https://github.com/vmg/sundown "Sundown"
diff --git a/vendor/src/github.com/russross/blackfriday/block.go b/vendor/src/github.com/russross/blackfriday/block.go
new file mode 100644
index 0000000..59c6d28
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/block.go
@@ -0,0 +1,1339 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Functions to parse block-level elements.
+//
+
+package blackfriday
+
+import (
+	"bytes"
+
+	"github.com/shurcooL/sanitized_anchor_name"
+)
+
+// Parse block-level data.
+// Note: this function and many that it calls assume that
+// the input buffer ends with a newline.
+func (p *parser) block(out *bytes.Buffer, data []byte) {
+	if len(data) == 0 || data[len(data)-1] != '\n' {
+		panic("block input is missing terminating newline")
+	}
+
+	// this is called recursively: enforce a maximum depth
+	if p.nesting >= p.maxNesting {
+		return
+	}
+	p.nesting++
+
+	// parse out one block-level construct at a time
+	for len(data) > 0 {
+		// prefixed header:
+		//
+		// # Header 1
+		// ## Header 2
+		// ...
+		// ###### Header 6
+		if p.isPrefixHeader(data) {
+			data = data[p.prefixHeader(out, data):]
+			continue
+		}
+
+		// block of preformatted HTML:
+		//
+		// <div>
+		//     ...
+		// </div>
+		if data[0] == '<' {
+			if i := p.html(out, data, true); i > 0 {
+				data = data[i:]
+				continue
+			}
+		}
+
+		// title block
+		//
+		// % stuff
+		// % more stuff
+		// % even more stuff
+		if p.flags&EXTENSION_TITLEBLOCK != 0 {
+			if data[0] == '%' {
+				if i := p.titleBlock(out, data, true); i > 0 {
+					data = data[i:]
+					continue
+				}
+			}
+		}
+
+		// blank lines.  note: returns the # of bytes to skip
+		if i := p.isEmpty(data); i > 0 {
+			data = data[i:]
+			continue
+		}
+
+		// indented code block:
+		//
+		//     func max(a, b int) int {
+		//         if a > b {
+		//             return a
+		//         }
+		//         return b
+		//      }
+		if p.codePrefix(data) > 0 {
+			data = data[p.code(out, data):]
+			continue
+		}
+
+		// fenced code block:
+		//
+		// ``` go
+		// func fact(n int) int {
+		//     if n <= 1 {
+		//         return n
+		//     }
+		//     return n * fact(n-1)
+		// }
+		// ```
+		if p.flags&EXTENSION_FENCED_CODE != 0 {
+			if i := p.fencedCode(out, data, true); i > 0 {
+				data = data[i:]
+				continue
+			}
+		}
+
+		// horizontal rule:
+		//
+		// ------
+		// or
+		// ******
+		// or
+		// ______
+		if p.isHRule(data) {
+			p.r.HRule(out)
+			var i int
+			for i = 0; data[i] != '\n'; i++ {
+			}
+			data = data[i:]
+			continue
+		}
+
+		// block quote:
+		//
+		// > A big quote I found somewhere
+		// > on the web
+		if p.quotePrefix(data) > 0 {
+			data = data[p.quote(out, data):]
+			continue
+		}
+
+		// table:
+		//
+		// Name  | Age | Phone
+		// ------|-----|---------
+		// Bob   | 31  | 555-1234
+		// Alice | 27  | 555-4321
+		if p.flags&EXTENSION_TABLES != 0 {
+			if i := p.table(out, data); i > 0 {
+				data = data[i:]
+				continue
+			}
+		}
+
+		// an itemized/unordered list:
+		//
+		// * Item 1
+		// * Item 2
+		//
+		// also works with + or -
+		if p.uliPrefix(data) > 0 {
+			data = data[p.list(out, data, 0):]
+			continue
+		}
+
+		// a numbered/ordered list:
+		//
+		// 1. Item 1
+		// 2. Item 2
+		if p.oliPrefix(data) > 0 {
+			data = data[p.list(out, data, LIST_TYPE_ORDERED):]
+			continue
+		}
+
+		// anything else must look like a normal paragraph
+		// note: this finds underlined headers, too
+		data = data[p.paragraph(out, data):]
+	}
+
+	p.nesting--
+}
+
+func (p *parser) isPrefixHeader(data []byte) bool {
+	if data[0] != '#' {
+		return false
+	}
+
+	if p.flags&EXTENSION_SPACE_HEADERS != 0 {
+		level := 0
+		for level < 6 && data[level] == '#' {
+			level++
+		}
+		if data[level] != ' ' {
+			return false
+		}
+	}
+	return true
+}
+
+func (p *parser) prefixHeader(out *bytes.Buffer, data []byte) int {
+	level := 0
+	for level < 6 && data[level] == '#' {
+		level++
+	}
+	i, end := 0, 0
+	for i = level; data[i] == ' '; i++ {
+	}
+	for end = i; data[end] != '\n'; end++ {
+	}
+	skip := end
+	id := ""
+	if p.flags&EXTENSION_HEADER_IDS != 0 {
+		j, k := 0, 0
+		// find start/end of header id
+		for j = i; j < end-1 && (data[j] != '{' || data[j+1] != '#'); j++ {
+		}
+		for k = j + 1; k < end && data[k] != '}'; k++ {
+		}
+		// extract header id iff found
+		if j < end && k < end {
+			id = string(data[j+2 : k])
+			end = j
+			skip = k + 1
+			for end > 0 && data[end-1] == ' ' {
+				end--
+			}
+		}
+	}
+	for end > 0 && data[end-1] == '#' {
+		end--
+	}
+	for end > 0 && data[end-1] == ' ' {
+		end--
+	}
+	if end > i {
+		if id == "" && p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
+			id = sanitized_anchor_name.Create(string(data[i:end]))
+		}
+		work := func() bool {
+			p.inline(out, data[i:end])
+			return true
+		}
+		p.r.Header(out, work, level, id)
+	}
+	return skip
+}
+
+func (p *parser) isUnderlinedHeader(data []byte) int {
+	// test of level 1 header
+	if data[0] == '=' {
+		i := 1
+		for data[i] == '=' {
+			i++
+		}
+		for data[i] == ' ' {
+			i++
+		}
+		if data[i] == '\n' {
+			return 1
+		} else {
+			return 0
+		}
+	}
+
+	// test of level 2 header
+	if data[0] == '-' {
+		i := 1
+		for data[i] == '-' {
+			i++
+		}
+		for data[i] == ' ' {
+			i++
+		}
+		if data[i] == '\n' {
+			return 2
+		} else {
+			return 0
+		}
+	}
+
+	return 0
+}
+
+func (p *parser) titleBlock(out *bytes.Buffer, data []byte, doRender bool) int {
+	if data[0] != '%' {
+		return 0
+	}
+	splitData := bytes.Split(data, []byte("\n"))
+	var i int
+	for idx, b := range splitData {
+		if !bytes.HasPrefix(b, []byte("%")) {
+			i = idx // - 1
+			break
+		}
+	}
+
+	data = bytes.Join(splitData[0:i], []byte("\n"))
+	p.r.TitleBlock(out, data)
+
+	return len(data)
+}
+
+func (p *parser) html(out *bytes.Buffer, data []byte, doRender bool) int {
+	var i, j int
+
+	// identify the opening tag
+	if data[0] != '<' {
+		return 0
+	}
+	curtag, tagfound := p.htmlFindTag(data[1:])
+
+	// handle special cases
+	if !tagfound {
+		// check for an HTML comment
+		if size := p.htmlComment(out, data, doRender); size > 0 {
+			return size
+		}
+
+		// check for an <hr> tag
+		if size := p.htmlHr(out, data, doRender); size > 0 {
+			return size
+		}
+
+		// no special case recognized
+		return 0
+	}
+
+	// look for an unindented matching closing tag
+	// followed by a blank line
+	found := false
+	/*
+		closetag := []byte("\n</" + curtag + ">")
+		j = len(curtag) + 1
+		for !found {
+			// scan for a closing tag at the beginning of a line
+			if skip := bytes.Index(data[j:], closetag); skip >= 0 {
+				j += skip + len(closetag)
+			} else {
+				break
+			}
+
+			// see if it is the only thing on the line
+			if skip := p.isEmpty(data[j:]); skip > 0 {
+				// see if it is followed by a blank line/eof
+				j += skip
+				if j >= len(data) {
+					found = true
+					i = j
+				} else {
+					if skip := p.isEmpty(data[j:]); skip > 0 {
+						j += skip
+						found = true
+						i = j
+					}
+				}
+			}
+		}
+	*/
+
+	// if not found, try a second pass looking for indented match
+	// but not if tag is "ins" or "del" (following original Markdown.pl)
+	if !found && curtag != "ins" && curtag != "del" {
+		i = 1
+		for i < len(data) {
+			i++
+			for i < len(data) && !(data[i-1] == '<' && data[i] == '/') {
+				i++
+			}
+
+			if i+2+len(curtag) >= len(data) {
+				break
+			}
+
+			j = p.htmlFindEnd(curtag, data[i-1:])
+
+			if j > 0 {
+				i += j - 1
+				found = true
+				break
+			}
+		}
+	}
+
+	if !found {
+		return 0
+	}
+
+	// the end of the block has been found
+	if doRender {
+		// trim newlines
+		end := i
+		for end > 0 && data[end-1] == '\n' {
+			end--
+		}
+		p.r.BlockHtml(out, data[:end])
+	}
+
+	return i
+}
+
+// HTML comment, lax form
+func (p *parser) htmlComment(out *bytes.Buffer, data []byte, doRender bool) int {
+	if data[0] != '<' || data[1] != '!' || data[2] != '-' || data[3] != '-' {
+		return 0
+	}
+
+	i := 5
+
+	// scan for an end-of-comment marker, across lines if necessary
+	for i < len(data) && !(data[i-2] == '-' && data[i-1] == '-' && data[i] == '>') {
+		i++
+	}
+	i++
+
+	// no end-of-comment marker
+	if i >= len(data) {
+		return 0
+	}
+
+	// needs to end with a blank line
+	if j := p.isEmpty(data[i:]); j > 0 {
+		size := i + j
+		if doRender {
+			// trim trailing newlines
+			end := size
+			for end > 0 && data[end-1] == '\n' {
+				end--
+			}
+			p.r.BlockHtml(out, data[:end])
+		}
+		return size
+	}
+
+	return 0
+}
+
+// HR, which is the only self-closing block tag considered
+func (p *parser) htmlHr(out *bytes.Buffer, data []byte, doRender bool) int {
+	if data[0] != '<' || (data[1] != 'h' && data[1] != 'H') || (data[2] != 'r' && data[2] != 'R') {
+		return 0
+	}
+	if data[3] != ' ' && data[3] != '/' && data[3] != '>' {
+		// not an <hr> tag after all; at least not a valid one
+		return 0
+	}
+
+	i := 3
+	for data[i] != '>' && data[i] != '\n' {
+		i++
+	}
+
+	if data[i] == '>' {
+		i++
+		if j := p.isEmpty(data[i:]); j > 0 {
+			size := i + j
+			if doRender {
+				// trim newlines
+				end := size
+				for end > 0 && data[end-1] == '\n' {
+					end--
+				}
+				p.r.BlockHtml(out, data[:end])
+			}
+			return size
+		}
+	}
+
+	return 0
+}
+
+func (p *parser) htmlFindTag(data []byte) (string, bool) {
+	i := 0
+	for isalnum(data[i]) {
+		i++
+	}
+	key := string(data[:i])
+	if blockTags[key] {
+		return key, true
+	}
+	return "", false
+}
+
+func (p *parser) htmlFindEnd(tag string, data []byte) int {
+	// assume data[0] == '<' && data[1] == '/' already tested
+
+	// check if tag is a match
+	closetag := []byte("</" + tag + ">")
+	if !bytes.HasPrefix(data, closetag) {
+		return 0
+	}
+	i := len(closetag)
+
+	// check that the rest of the line is blank
+	skip := 0
+	if skip = p.isEmpty(data[i:]); skip == 0 {
+		return 0
+	}
+	i += skip
+	skip = 0
+
+	if i >= len(data) {
+		return i
+	}
+
+	if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 {
+		return i
+	}
+	if skip = p.isEmpty(data[i:]); skip == 0 {
+		// following line must be blank
+		return 0
+	}
+
+	return i + skip
+}
+
+func (p *parser) isEmpty(data []byte) int {
+	// it is okay to call isEmpty on an empty buffer
+	if len(data) == 0 {
+		return 0
+	}
+
+	var i int
+	for i = 0; i < len(data) && data[i] != '\n'; i++ {
+		if data[i] != ' ' && data[i] != '\t' {
+			return 0
+		}
+	}
+	return i + 1
+}
+
+func (p *parser) isHRule(data []byte) bool {
+	i := 0
+
+	// skip up to three spaces
+	for i < 3 && data[i] == ' ' {
+		i++
+	}
+
+	// look at the hrule char
+	if data[i] != '*' && data[i] != '-' && data[i] != '_' {
+		return false
+	}
+	c := data[i]
+
+	// the whole line must be the char or whitespace
+	n := 0
+	for data[i] != '\n' {
+		switch {
+		case data[i] == c:
+			n++
+		case data[i] != ' ':
+			return false
+		}
+		i++
+	}
+
+	return n >= 3
+}
+
+func (p *parser) isFencedCode(data []byte, syntax **string, oldmarker string) (skip int, marker string) {
+	i, size := 0, 0
+	skip = 0
+
+	// skip up to three spaces
+	for i < len(data) && i < 3 && data[i] == ' ' {
+		i++
+	}
+	if i >= len(data) {
+		return
+	}
+
+	// check for the marker characters: ~ or `
+	if data[i] != '~' && data[i] != '`' {
+		return
+	}
+
+	c := data[i]
+
+	// the whole line must be the same char or whitespace
+	for i < len(data) && data[i] == c {
+		size++
+		i++
+	}
+
+	if i >= len(data) {
+		return
+	}
+
+	// the marker char must occur at least 3 times
+	if size < 3 {
+		return
+	}
+	marker = string(data[i-size : i])
+
+	// if this is the end marker, it must match the beginning marker
+	if oldmarker != "" && marker != oldmarker {
+		return
+	}
+
+	if syntax != nil {
+		syn := 0
+
+		for i < len(data) && data[i] == ' ' {
+			i++
+		}
+
+		if i >= len(data) {
+			return
+		}
+
+		syntaxStart := i
+
+		if data[i] == '{' {
+			i++
+			syntaxStart++
+
+			for i < len(data) && data[i] != '}' && data[i] != '\n' {
+				syn++
+				i++
+			}
+
+			if i >= len(data) || data[i] != '}' {
+				return
+			}
+
+			// strip all whitespace at the beginning and the end
+			// of the {} block
+			for syn > 0 && isspace(data[syntaxStart]) {
+				syntaxStart++
+				syn--
+			}
+
+			for syn > 0 && isspace(data[syntaxStart+syn-1]) {
+				syn--
+			}
+
+			i++
+		} else {
+			for i < len(data) && !isspace(data[i]) {
+				syn++
+				i++
+			}
+		}
+
+		language := string(data[syntaxStart : syntaxStart+syn])
+		*syntax = &language
+	}
+
+	for i < len(data) && data[i] == ' ' {
+		i++
+	}
+	if i >= len(data) || data[i] != '\n' {
+		return
+	}
+
+	skip = i + 1
+	return
+}
+
+func (p *parser) fencedCode(out *bytes.Buffer, data []byte, doRender bool) int {
+	var lang *string
+	beg, marker := p.isFencedCode(data, &lang, "")
+	if beg == 0 || beg >= len(data) {
+		return 0
+	}
+
+	var work bytes.Buffer
+
+	for {
+		// safe to assume beg < len(data)
+
+		// check for the end of the code block
+		fenceEnd, _ := p.isFencedCode(data[beg:], nil, marker)
+		if fenceEnd != 0 {
+			beg += fenceEnd
+			break
+		}
+
+		// copy the current line
+		end := beg
+		for end < len(data) && data[end] != '\n' {
+			end++
+		}
+		end++
+
+		// did we reach the end of the buffer without a closing marker?
+		if end >= len(data) {
+			return 0
+		}
+
+		// verbatim copy to the working buffer
+		if doRender {
+			work.Write(data[beg:end])
+		}
+		beg = end
+	}
+
+	syntax := ""
+	if lang != nil {
+		syntax = *lang
+	}
+
+	if doRender {
+		p.r.BlockCode(out, work.Bytes(), syntax)
+	}
+
+	return beg
+}
+
+func (p *parser) table(out *bytes.Buffer, data []byte) int {
+	var header bytes.Buffer
+	i, columns := p.tableHeader(&header, data)
+	if i == 0 {
+		return 0
+	}
+
+	var body bytes.Buffer
+
+	for i < len(data) {
+		pipes, rowStart := 0, i
+		for ; data[i] != '\n'; i++ {
+			if data[i] == '|' {
+				pipes++
+			}
+		}
+
+		if pipes == 0 {
+			i = rowStart
+			break
+		}
+
+		// include the newline in data sent to tableRow
+		i++
+		p.tableRow(&body, data[rowStart:i], columns, false)
+	}
+
+	p.r.Table(out, header.Bytes(), body.Bytes(), columns)
+
+	return i
+}
+
+// check if the specified position is preceeded by an odd number of backslashes
+func isBackslashEscaped(data []byte, i int) bool {
+	backslashes := 0
+	for i-backslashes-1 >= 0 && data[i-backslashes-1] == '\\' {
+		backslashes++
+	}
+	return backslashes&1 == 1
+}
+
+func (p *parser) tableHeader(out *bytes.Buffer, data []byte) (size int, columns []int) {
+	i := 0
+	colCount := 1
+	for i = 0; data[i] != '\n'; i++ {
+		if data[i] == '|' && !isBackslashEscaped(data, i) {
+			colCount++
+		}
+	}
+
+	// doesn't look like a table header
+	if colCount == 1 {
+		return
+	}
+
+	// include the newline in the data sent to tableRow
+	header := data[:i+1]
+
+	// column count ignores pipes at beginning or end of line
+	if data[0] == '|' {
+		colCount--
+	}
+	if i > 2 && data[i-1] == '|' && !isBackslashEscaped(data, i-1) {
+		colCount--
+	}
+
+	columns = make([]int, colCount)
+
+	// move on to the header underline
+	i++
+	if i >= len(data) {
+		return
+	}
+
+	if data[i] == '|' && !isBackslashEscaped(data, i) {
+		i++
+	}
+	for data[i] == ' ' {
+		i++
+	}
+
+	// each column header is of form: / *:?-+:? *|/ with # dashes + # colons >= 3
+	// and trailing | optional on last column
+	col := 0
+	for data[i] != '\n' {
+		dashes := 0
+
+		if data[i] == ':' {
+			i++
+			columns[col] |= TABLE_ALIGNMENT_LEFT
+			dashes++
+		}
+		for data[i] == '-' {
+			i++
+			dashes++
+		}
+		if data[i] == ':' {
+			i++
+			columns[col] |= TABLE_ALIGNMENT_RIGHT
+			dashes++
+		}
+		for data[i] == ' ' {
+			i++
+		}
+
+		// end of column test is messy
+		switch {
+		case dashes < 3:
+			// not a valid column
+			return
+
+		case data[i] == '|' && !isBackslashEscaped(data, i):
+			// marker found, now skip past trailing whitespace
+			col++
+			i++
+			for data[i] == ' ' {
+				i++
+			}
+
+			// trailing junk found after last column
+			if col >= colCount && data[i] != '\n' {
+				return
+			}
+
+		case (data[i] != '|' || isBackslashEscaped(data, i)) && col+1 < colCount:
+			// something else found where marker was required
+			return
+
+		case data[i] == '\n':
+			// marker is optional for the last column
+			col++
+
+		default:
+			// trailing junk found after last column
+			return
+		}
+	}
+	if col != colCount {
+		return
+	}
+
+	p.tableRow(out, header, columns, true)
+	size = i + 1
+	return
+}
+
+func (p *parser) tableRow(out *bytes.Buffer, data []byte, columns []int, header bool) {
+	i, col := 0, 0
+	var rowWork bytes.Buffer
+
+	if data[i] == '|' && !isBackslashEscaped(data, i) {
+		i++
+	}
+
+	for col = 0; col < len(columns) && i < len(data); col++ {
+		for data[i] == ' ' {
+			i++
+		}
+
+		cellStart := i
+
+		for (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
+			i++
+		}
+
+		cellEnd := i
+
+		// skip the end-of-cell marker, possibly taking us past end of buffer
+		i++
+
+		for cellEnd > cellStart && data[cellEnd-1] == ' ' {
+			cellEnd--
+		}
+
+		var cellWork bytes.Buffer
+		p.inline(&cellWork, data[cellStart:cellEnd])
+
+		if header {
+			p.r.TableHeaderCell(&rowWork, cellWork.Bytes(), columns[col])
+		} else {
+			p.r.TableCell(&rowWork, cellWork.Bytes(), columns[col])
+		}
+	}
+
+	// pad it out with empty columns to get the right number
+	for ; col < len(columns); col++ {
+		if header {
+			p.r.TableHeaderCell(&rowWork, nil, columns[col])
+		} else {
+			p.r.TableCell(&rowWork, nil, columns[col])
+		}
+	}
+
+	// silently ignore rows with too many cells
+
+	p.r.TableRow(out, rowWork.Bytes())
+}
+
+// returns blockquote prefix length
+func (p *parser) quotePrefix(data []byte) int {
+	i := 0
+	for i < 3 && data[i] == ' ' {
+		i++
+	}
+	if data[i] == '>' {
+		if data[i+1] == ' ' {
+			return i + 2
+		}
+		return i + 1
+	}
+	return 0
+}
+
+// parse a blockquote fragment
+func (p *parser) quote(out *bytes.Buffer, data []byte) int {
+	var raw bytes.Buffer
+	beg, end := 0, 0
+	for beg < len(data) {
+		end = beg
+		for data[end] != '\n' {
+			end++
+		}
+		end++
+
+		if pre := p.quotePrefix(data[beg:]); pre > 0 {
+			// skip the prefix
+			beg += pre
+		} else if p.isEmpty(data[beg:]) > 0 &&
+			(end >= len(data) ||
+				(p.quotePrefix(data[end:]) == 0 && p.isEmpty(data[end:]) == 0)) {
+			// blockquote ends with at least one blank line
+			// followed by something without a blockquote prefix
+			break
+		}
+
+		// this line is part of the blockquote
+		raw.Write(data[beg:end])
+		beg = end
+	}
+
+	var cooked bytes.Buffer
+	p.block(&cooked, raw.Bytes())
+	p.r.BlockQuote(out, cooked.Bytes())
+	return end
+}
+
+// returns prefix length for block code
+func (p *parser) codePrefix(data []byte) int {
+	if data[0] == ' ' && data[1] == ' ' && data[2] == ' ' && data[3] == ' ' {
+		return 4
+	}
+	return 0
+}
+
+func (p *parser) code(out *bytes.Buffer, data []byte) int {
+	var work bytes.Buffer
+
+	i := 0
+	for i < len(data) {
+		beg := i
+		for data[i] != '\n' {
+			i++
+		}
+		i++
+
+		blankline := p.isEmpty(data[beg:i]) > 0
+		if pre := p.codePrefix(data[beg:i]); pre > 0 {
+			beg += pre
+		} else if !blankline {
+			// non-empty, non-prefixed line breaks the pre
+			i = beg
+			break
+		}
+
+		// verbatim copy to the working buffeu
+		if blankline {
+			work.WriteByte('\n')
+		} else {
+			work.Write(data[beg:i])
+		}
+	}
+
+	// trim all the \n off the end of work
+	workbytes := work.Bytes()
+	eol := len(workbytes)
+	for eol > 0 && workbytes[eol-1] == '\n' {
+		eol--
+	}
+	if eol != len(workbytes) {
+		work.Truncate(eol)
+	}
+
+	work.WriteByte('\n')
+
+	p.r.BlockCode(out, work.Bytes(), "")
+
+	return i
+}
+
+// returns unordered list item prefix
+func (p *parser) uliPrefix(data []byte) int {
+	i := 0
+
+	// start with up to 3 spaces
+	for i < 3 && data[i] == ' ' {
+		i++
+	}
+
+	// need a *, +, or - followed by a space
+	if (data[i] != '*' && data[i] != '+' && data[i] != '-') ||
+		data[i+1] != ' ' {
+		return 0
+	}
+	return i + 2
+}
+
+// returns ordered list item prefix
+func (p *parser) oliPrefix(data []byte) int {
+	i := 0
+
+	// start with up to 3 spaces
+	for i < 3 && data[i] == ' ' {
+		i++
+	}
+
+	// count the digits
+	start := i
+	for data[i] >= '0' && data[i] <= '9' {
+		i++
+	}
+
+	// we need >= 1 digits followed by a dot and a space
+	if start == i || data[i] != '.' || data[i+1] != ' ' {
+		return 0
+	}
+	return i + 2
+}
+
+// parse ordered or unordered list block
+func (p *parser) list(out *bytes.Buffer, data []byte, flags int) int {
+	i := 0
+	flags |= LIST_ITEM_BEGINNING_OF_LIST
+	work := func() bool {
+		for i < len(data) {
+			skip := p.listItem(out, data[i:], &flags)
+			i += skip
+
+			if skip == 0 || flags&LIST_ITEM_END_OF_LIST != 0 {
+				break
+			}
+			flags &= ^LIST_ITEM_BEGINNING_OF_LIST
+		}
+		return true
+	}
+
+	p.r.List(out, work, flags)
+	return i
+}
+
+// Parse a single list item.
+// Assumes initial prefix is already removed if this is a sublist.
+func (p *parser) listItem(out *bytes.Buffer, data []byte, flags *int) int {
+	// keep track of the indentation of the first line
+	itemIndent := 0
+	for itemIndent < 3 && data[itemIndent] == ' ' {
+		itemIndent++
+	}
+
+	i := p.uliPrefix(data)
+	if i == 0 {
+		i = p.oliPrefix(data)
+	}
+	if i == 0 {
+		return 0
+	}
+
+	// skip leading whitespace on first line
+	for data[i] == ' ' {
+		i++
+	}
+
+	// find the end of the line
+	line := i
+	for data[i-1] != '\n' {
+		i++
+	}
+
+	// get working buffer
+	var raw bytes.Buffer
+
+	// put the first line into the working buffer
+	raw.Write(data[line:i])
+	line = i
+
+	// process the following lines
+	containsBlankLine := false
+	sublist := 0
+
+gatherlines:
+	for line < len(data) {
+		i++
+
+		// find the end of this line
+		for data[i-1] != '\n' {
+			i++
+		}
+
+		// if it is an empty line, guess that it is part of this item
+		// and move on to the next line
+		if p.isEmpty(data[line:i]) > 0 {
+			containsBlankLine = true
+			line = i
+			continue
+		}
+
+		// calculate the indentation
+		indent := 0
+		for indent < 4 && line+indent < i && data[line+indent] == ' ' {
+			indent++
+		}
+
+		chunk := data[line+indent : i]
+
+		// evaluate how this line fits in
+		switch {
+		// is this a nested list item?
+		case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) ||
+			p.oliPrefix(chunk) > 0:
+
+			if containsBlankLine {
+				*flags |= LIST_ITEM_CONTAINS_BLOCK
+			}
+
+			// to be a nested list, it must be indented more
+			// if not, it is the next item in the same list
+			if indent <= itemIndent {
+				break gatherlines
+			}
+
+			// is this the first item in the the nested list?
+			if sublist == 0 {
+				sublist = raw.Len()
+			}
+
+		// is this a nested prefix header?
+		case p.isPrefixHeader(chunk):
+			// if the header is not indented, it is not nested in the list
+			// and thus ends the list
+			if containsBlankLine && indent < 4 {
+				*flags |= LIST_ITEM_END_OF_LIST
+				break gatherlines
+			}
+			*flags |= LIST_ITEM_CONTAINS_BLOCK
+
+		// anything following an empty line is only part
+		// of this item if it is indented 4 spaces
+		// (regardless of the indentation of the beginning of the item)
+		case containsBlankLine && indent < 4:
+			*flags |= LIST_ITEM_END_OF_LIST
+			break gatherlines
+
+		// a blank line means this should be parsed as a block
+		case containsBlankLine:
+			raw.WriteByte('\n')
+			*flags |= LIST_ITEM_CONTAINS_BLOCK
+		}
+
+		// if this line was preceeded by one or more blanks,
+		// re-introduce the blank into the buffer
+		if containsBlankLine {
+			containsBlankLine = false
+			raw.WriteByte('\n')
+		}
+
+		// add the line into the working buffer without prefix
+		raw.Write(data[line+indent : i])
+
+		line = i
+	}
+
+	rawBytes := raw.Bytes()
+
+	// render the contents of the list item
+	var cooked bytes.Buffer
+	if *flags&LIST_ITEM_CONTAINS_BLOCK != 0 {
+		// intermediate render of block li
+		if sublist > 0 {
+			p.block(&cooked, rawBytes[:sublist])
+			p.block(&cooked, rawBytes[sublist:])
+		} else {
+			p.block(&cooked, rawBytes)
+		}
+	} else {
+		// intermediate render of inline li
+		if sublist > 0 {
+			p.inline(&cooked, rawBytes[:sublist])
+			p.block(&cooked, rawBytes[sublist:])
+		} else {
+			p.inline(&cooked, rawBytes)
+		}
+	}
+
+	// render the actual list item
+	cookedBytes := cooked.Bytes()
+	parsedEnd := len(cookedBytes)
+
+	// strip trailing newlines
+	for parsedEnd > 0 && cookedBytes[parsedEnd-1] == '\n' {
+		parsedEnd--
+	}
+	p.r.ListItem(out, cookedBytes[:parsedEnd], *flags)
+
+	return line
+}
+
+// render a single paragraph that has already been parsed out
+func (p *parser) renderParagraph(out *bytes.Buffer, data []byte) {
+	if len(data) == 0 {
+		return
+	}
+
+	// trim leading spaces
+	beg := 0
+	for data[beg] == ' ' {
+		beg++
+	}
+
+	// trim trailing newline
+	end := len(data) - 1
+
+	// trim trailing spaces
+	for end > beg && data[end-1] == ' ' {
+		end--
+	}
+
+	work := func() bool {
+		p.inline(out, data[beg:end])
+		return true
+	}
+	p.r.Paragraph(out, work)
+}
+
+func (p *parser) paragraph(out *bytes.Buffer, data []byte) int {
+	// prev: index of 1st char of previous line
+	// line: index of 1st char of current line
+	// i: index of cursor/end of current line
+	var prev, line, i int
+
+	// keep going until we find something to mark the end of the paragraph
+	for i < len(data) {
+		// mark the beginning of the current line
+		prev = line
+		current := data[i:]
+		line = i
+
+		// did we find a blank line marking the end of the paragraph?
+		if n := p.isEmpty(current); n > 0 {
+			p.renderParagraph(out, data[:i])
+			return i + n
+		}
+
+		// an underline under some text marks a header, so our paragraph ended on prev line
+		if i > 0 {
+			if level := p.isUnderlinedHeader(current); level > 0 {
+				// render the paragraph
+				p.renderParagraph(out, data[:prev])
+
+				// ignore leading and trailing whitespace
+				eol := i - 1
+				for prev < eol && data[prev] == ' ' {
+					prev++
+				}
+				for eol > prev && data[eol-1] == ' ' {
+					eol--
+				}
+
+				// render the header
+				// this ugly double closure avoids forcing variables onto the heap
+				work := func(o *bytes.Buffer, pp *parser, d []byte) func() bool {
+					return func() bool {
+						pp.inline(o, d)
+						return true
+					}
+				}(out, p, data[prev:eol])
+
+				id := ""
+				if p.flags&EXTENSION_AUTO_HEADER_IDS != 0 {
+					id = sanitized_anchor_name.Create(string(data[prev:eol]))
+				}
+
+				p.r.Header(out, work, level, id)
+
+				// find the end of the underline
+				for data[i] != '\n' {
+					i++
+				}
+				return i
+			}
+		}
+
+		// if the next line starts a block of HTML, then the paragraph ends here
+		if p.flags&EXTENSION_LAX_HTML_BLOCKS != 0 {
+			if data[i] == '<' && p.html(out, current, false) > 0 {
+				// rewind to before the HTML block
+				p.renderParagraph(out, data[:i])
+				return i
+			}
+		}
+
+		// if there's a prefixed header or a horizontal rule after this, paragraph is over
+		if p.isPrefixHeader(current) || p.isHRule(current) {
+			p.renderParagraph(out, data[:i])
+			return i
+		}
+
+		// if there's a list after this, paragraph is over
+		if p.flags&EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK != 0 {
+			if p.uliPrefix(current) != 0 ||
+				p.oliPrefix(current) != 0 ||
+				p.quotePrefix(current) != 0 ||
+				p.codePrefix(current) != 0 {
+				p.renderParagraph(out, data[:i])
+				return i
+			}
+		}
+
+		// otherwise, scan to the beginning of the next line
+		for data[i] != '\n' {
+			i++
+		}
+		i++
+	}
+
+	p.renderParagraph(out, data[:i])
+	return i
+}
diff --git a/vendor/src/github.com/russross/blackfriday/block_test.go b/vendor/src/github.com/russross/blackfriday/block_test.go
new file mode 100644
index 0000000..b726c07
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/block_test.go
@@ -0,0 +1,1296 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Unit tests for block parsing
+//
+
+package blackfriday
+
+import (
+	"testing"
+)
+
+func runMarkdownBlockWithRenderer(input string, extensions int, renderer Renderer) string {
+	return string(Markdown([]byte(input), renderer, extensions))
+}
+
+func runMarkdownBlock(input string, extensions int) string {
+	htmlFlags := 0
+	htmlFlags |= HTML_USE_XHTML
+
+	renderer := HtmlRenderer(htmlFlags, "", "")
+
+	return runMarkdownBlockWithRenderer(input, extensions, renderer)
+}
+
+func runnerWithRendererParameters(parameters HtmlRendererParameters) func(string, int) string {
+	return func(input string, extensions int) string {
+		htmlFlags := 0
+		htmlFlags |= HTML_USE_XHTML
+
+		renderer := HtmlRendererWithParameters(htmlFlags, "", "", parameters)
+
+		return runMarkdownBlockWithRenderer(input, extensions, renderer)
+	}
+}
+
+func doTestsBlock(t *testing.T, tests []string, extensions int) {
+	doTestsBlockWithRunner(t, tests, extensions, runMarkdownBlock)
+}
+
+func doTestsBlockWithRunner(t *testing.T, tests []string, extensions int, runner func(string, int) string) {
+	// catch and report panics
+	var candidate string
+	defer func() {
+		if err := recover(); err != nil {
+			t.Errorf("\npanic while processing [%#v]: %s\n", candidate, err)
+		}
+	}()
+
+	for i := 0; i+1 < len(tests); i += 2 {
+		input := tests[i]
+		candidate = input
+		expected := tests[i+1]
+		actual := runner(candidate, extensions)
+		if actual != expected {
+			t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
+				candidate, expected, actual)
+		}
+
+		// now test every substring to stress test bounds checking
+		if !testing.Short() {
+			for start := 0; start < len(input); start++ {
+				for end := start + 1; end <= len(input); end++ {
+					candidate = input[start:end]
+					_ = runMarkdownBlock(candidate, extensions)
+				}
+			}
+		}
+	}
+}
+
+func TestPrefixHeaderNoExtensions(t *testing.T) {
+	var tests = []string{
+		"# Header 1\n",
+		"<h1>Header 1</h1>\n",
+
+		"## Header 2\n",
+		"<h2>Header 2</h2>\n",
+
+		"### Header 3\n",
+		"<h3>Header 3</h3>\n",
+
+		"#### Header 4\n",
+		"<h4>Header 4</h4>\n",
+
+		"##### Header 5\n",
+		"<h5>Header 5</h5>\n",
+
+		"###### Header 6\n",
+		"<h6>Header 6</h6>\n",
+
+		"####### Header 7\n",
+		"<h6># Header 7</h6>\n",
+
+		"#Header 1\n",
+		"<h1>Header 1</h1>\n",
+
+		"##Header 2\n",
+		"<h2>Header 2</h2>\n",
+
+		"###Header 3\n",
+		"<h3>Header 3</h3>\n",
+
+		"####Header 4\n",
+		"<h4>Header 4</h4>\n",
+
+		"#####Header 5\n",
+		"<h5>Header 5</h5>\n",
+
+		"######Header 6\n",
+		"<h6>Header 6</h6>\n",
+
+		"#######Header 7\n",
+		"<h6>#Header 7</h6>\n",
+
+		"Hello\n# Header 1\nGoodbye\n",
+		"<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
+
+		"* List\n# Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestPrefixHeaderSpaceExtension(t *testing.T) {
+	var tests = []string{
+		"# Header 1\n",
+		"<h1>Header 1</h1>\n",
+
+		"## Header 2\n",
+		"<h2>Header 2</h2>\n",
+
+		"### Header 3\n",
+		"<h3>Header 3</h3>\n",
+
+		"#### Header 4\n",
+		"<h4>Header 4</h4>\n",
+
+		"##### Header 5\n",
+		"<h5>Header 5</h5>\n",
+
+		"###### Header 6\n",
+		"<h6>Header 6</h6>\n",
+
+		"####### Header 7\n",
+		"<p>####### Header 7</p>\n",
+
+		"#Header 1\n",
+		"<p>#Header 1</p>\n",
+
+		"##Header 2\n",
+		"<p>##Header 2</p>\n",
+
+		"###Header 3\n",
+		"<p>###Header 3</p>\n",
+
+		"####Header 4\n",
+		"<p>####Header 4</p>\n",
+
+		"#####Header 5\n",
+		"<p>#####Header 5</p>\n",
+
+		"######Header 6\n",
+		"<p>######Header 6</p>\n",
+
+		"#######Header 7\n",
+		"<p>#######Header 7</p>\n",
+
+		"Hello\n# Header 1\nGoodbye\n",
+		"<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
+
+		"* List\n# Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1>Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header\n* List\n",
+		"<ul>\n<li>List\n#Header</li>\n<li>List</li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1>Nested header</h1></li>\n</ul></li>\n</ul>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_SPACE_HEADERS)
+}
+
+func TestPrefixHeaderIdExtension(t *testing.T) {
+	var tests = []string{
+		"# Header 1 {#someid}\n",
+		"<h1 id=\"someid\">Header 1</h1>\n",
+
+		"# Header 1 {#someid}   \n",
+		"<h1 id=\"someid\">Header 1</h1>\n",
+
+		"# Header 1         {#someid}\n",
+		"<h1 id=\"someid\">Header 1</h1>\n",
+
+		"# Header 1 {#someid\n",
+		"<h1>Header 1 {#someid</h1>\n",
+
+		"# Header 1 {#someid\n",
+		"<h1>Header 1 {#someid</h1>\n",
+
+		"# Header 1 {#someid}}\n",
+		"<h1 id=\"someid\">Header 1</h1>\n\n<p>}</p>\n",
+
+		"## Header 2 {#someid}\n",
+		"<h2 id=\"someid\">Header 2</h2>\n",
+
+		"### Header 3 {#someid}\n",
+		"<h3 id=\"someid\">Header 3</h3>\n",
+
+		"#### Header 4 {#someid}\n",
+		"<h4 id=\"someid\">Header 4</h4>\n",
+
+		"##### Header 5 {#someid}\n",
+		"<h5 id=\"someid\">Header 5</h5>\n",
+
+		"###### Header 6 {#someid}\n",
+		"<h6 id=\"someid\">Header 6</h6>\n",
+
+		"####### Header 7 {#someid}\n",
+		"<h6 id=\"someid\"># Header 7</h6>\n",
+
+		"# Header 1 # {#someid}\n",
+		"<h1 id=\"someid\">Header 1</h1>\n",
+
+		"## Header 2 ## {#someid}\n",
+		"<h2 id=\"someid\">Header 2</h2>\n",
+
+		"Hello\n# Header 1\nGoodbye\n",
+		"<p>Hello</p>\n\n<h1>Header 1</h1>\n\n<p>Goodbye</p>\n",
+
+		"* List\n# Header {#someid}\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"someid\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header {#someid}\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"someid\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header {#someid}\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1 id=\"someid\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_HEADER_IDS)
+}
+
+func TestPrefixHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+	var tests = []string{
+		"# header 1 {#someid}\n",
+		"<h1 id=\"PRE:someid:POST\">header 1</h1>\n",
+
+		"## header 2 {#someid}\n",
+		"<h2 id=\"PRE:someid:POST\">header 2</h2>\n",
+
+		"### header 3 {#someid}\n",
+		"<h3 id=\"PRE:someid:POST\">header 3</h3>\n",
+
+		"#### header 4 {#someid}\n",
+		"<h4 id=\"PRE:someid:POST\">header 4</h4>\n",
+
+		"##### header 5 {#someid}\n",
+		"<h5 id=\"PRE:someid:POST\">header 5</h5>\n",
+
+		"###### header 6 {#someid}\n",
+		"<h6 id=\"PRE:someid:POST\">header 6</h6>\n",
+
+		"####### header 7 {#someid}\n",
+		"<h6 id=\"PRE:someid:POST\"># header 7</h6>\n",
+
+		"# header 1 # {#someid}\n",
+		"<h1 id=\"PRE:someid:POST\">header 1</h1>\n",
+
+		"## header 2 ## {#someid}\n",
+		"<h2 id=\"PRE:someid:POST\">header 2</h2>\n",
+
+		"* List\n# Header {#someid}\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:someid:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header {#someid}\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:someid:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header {#someid}\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1 id=\"PRE:someid:POST\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
+	}
+
+	parameters := HtmlRendererParameters{
+		HeaderIDPrefix: "PRE:",
+		HeaderIDSuffix: ":POST",
+	}
+
+	doTestsBlockWithRunner(t, tests, EXTENSION_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
+func TestPrefixAutoHeaderIdExtension(t *testing.T) {
+	var tests = []string{
+		"# Header 1\n",
+		"<h1 id=\"header-1\">Header 1</h1>\n",
+
+		"# Header 1   \n",
+		"<h1 id=\"header-1\">Header 1</h1>\n",
+
+		"## Header 2\n",
+		"<h2 id=\"header-2\">Header 2</h2>\n",
+
+		"### Header 3\n",
+		"<h3 id=\"header-3\">Header 3</h3>\n",
+
+		"#### Header 4\n",
+		"<h4 id=\"header-4\">Header 4</h4>\n",
+
+		"##### Header 5\n",
+		"<h5 id=\"header-5\">Header 5</h5>\n",
+
+		"###### Header 6\n",
+		"<h6 id=\"header-6\">Header 6</h6>\n",
+
+		"####### Header 7\n",
+		"<h6 id=\"header-7\"># Header 7</h6>\n",
+
+		"Hello\n# Header 1\nGoodbye\n",
+		"<p>Hello</p>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<p>Goodbye</p>\n",
+
+		"* List\n# Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"header\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1 id=\"nested-header\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
+
+		"# Header\n\n# Header\n",
+		"<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
+
+		"# Header 1\n\n# Header 1",
+		"<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
+
+		"# Header\n\n# Header 1\n\n# Header\n\n# Header",
+		"<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header</h1>\n\n<h1 id=\"header-1-2\">Header</h1>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS)
+}
+
+func TestPrefixAutoHeaderIdExtensionWithPrefixAndSuffix(t *testing.T) {
+	var tests = []string{
+		"# Header 1\n",
+		"<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
+
+		"# Header 1   \n",
+		"<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n",
+
+		"## Header 2\n",
+		"<h2 id=\"PRE:header-2:POST\">Header 2</h2>\n",
+
+		"### Header 3\n",
+		"<h3 id=\"PRE:header-3:POST\">Header 3</h3>\n",
+
+		"#### Header 4\n",
+		"<h4 id=\"PRE:header-4:POST\">Header 4</h4>\n",
+
+		"##### Header 5\n",
+		"<h5 id=\"PRE:header-5:POST\">Header 5</h5>\n",
+
+		"###### Header 6\n",
+		"<h6 id=\"PRE:header-6:POST\">Header 6</h6>\n",
+
+		"####### Header 7\n",
+		"<h6 id=\"PRE:header-7:POST\"># Header 7</h6>\n",
+
+		"Hello\n# Header 1\nGoodbye\n",
+		"<p>Hello</p>\n\n<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<p>Goodbye</p>\n",
+
+		"* List\n# Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:header:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"* List\n#Header\n* List\n",
+		"<ul>\n<li><p>List</p>\n\n<h1 id=\"PRE:header:POST\">Header</h1></li>\n\n<li><p>List</p></li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n    # Nested header\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li><p>Nested list</p>\n\n" +
+			"<h1 id=\"PRE:nested-header:POST\">Nested header</h1></li>\n</ul></li>\n</ul>\n",
+
+		"# Header\n\n# Header\n",
+		"<h1 id=\"PRE:header:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1:POST\">Header</h1>\n",
+
+		"# Header 1\n\n# Header 1",
+		"<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<h1 id=\"PRE:header-1-1:POST\">Header 1</h1>\n",
+
+		"# Header\n\n# Header 1\n\n# Header\n\n# Header",
+		"<h1 id=\"PRE:header:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1:POST\">Header 1</h1>\n\n<h1 id=\"PRE:header-1-1:POST\">Header</h1>\n\n<h1 id=\"PRE:header-1-2:POST\">Header</h1>\n",
+	}
+
+	parameters := HtmlRendererParameters{
+		HeaderIDPrefix: "PRE:",
+		HeaderIDSuffix: ":POST",
+	}
+
+	doTestsBlockWithRunner(t, tests, EXTENSION_AUTO_HEADER_IDS, runnerWithRendererParameters(parameters))
+}
+
+func TestPrefixMultipleHeaderExtensions(t *testing.T) {
+	var tests = []string{
+		"# Header\n\n# Header {#header}\n\n# Header 1",
+		"<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS|EXTENSION_HEADER_IDS)
+}
+
+func TestUnderlineHeaders(t *testing.T) {
+	var tests = []string{
+		"Header 1\n========\n",
+		"<h1>Header 1</h1>\n",
+
+		"Header 2\n--------\n",
+		"<h2>Header 2</h2>\n",
+
+		"A\n=\n",
+		"<h1>A</h1>\n",
+
+		"B\n-\n",
+		"<h2>B</h2>\n",
+
+		"Paragraph\nHeader\n=\n",
+		"<p>Paragraph</p>\n\n<h1>Header</h1>\n",
+
+		"Header\n===\nParagraph\n",
+		"<h1>Header</h1>\n\n<p>Paragraph</p>\n",
+
+		"Header\n===\nAnother header\n---\n",
+		"<h1>Header</h1>\n\n<h2>Another header</h2>\n",
+
+		"   Header\n======\n",
+		"<h1>Header</h1>\n",
+
+		"    Code\n========\n",
+		"<pre><code>Code\n</code></pre>\n\n<p>========</p>\n",
+
+		"Header with *inline*\n=====\n",
+		"<h1>Header with <em>inline</em></h1>\n",
+
+		"*   List\n    * Sublist\n    Not a header\n    ------\n",
+		"<ul>\n<li>List\n\n<ul>\n<li>Sublist\nNot a header\n------</li>\n</ul></li>\n</ul>\n",
+
+		"Paragraph\n\n\n\n\nHeader\n===\n",
+		"<p>Paragraph</p>\n\n<h1>Header</h1>\n",
+
+		"Trailing space \n====        \n\n",
+		"<h1>Trailing space</h1>\n",
+
+		"Trailing spaces\n====        \n\n",
+		"<h1>Trailing spaces</h1>\n",
+
+		"Double underline\n=====\n=====\n",
+		"<h1>Double underline</h1>\n\n<p>=====</p>\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestUnderlineHeadersAutoIDs(t *testing.T) {
+	var tests = []string{
+		"Header 1\n========\n",
+		"<h1 id=\"header-1\">Header 1</h1>\n",
+
+		"Header 2\n--------\n",
+		"<h2 id=\"header-2\">Header 2</h2>\n",
+
+		"A\n=\n",
+		"<h1 id=\"a\">A</h1>\n",
+
+		"B\n-\n",
+		"<h2 id=\"b\">B</h2>\n",
+
+		"Paragraph\nHeader\n=\n",
+		"<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
+
+		"Header\n===\nParagraph\n",
+		"<h1 id=\"header\">Header</h1>\n\n<p>Paragraph</p>\n",
+
+		"Header\n===\nAnother header\n---\n",
+		"<h1 id=\"header\">Header</h1>\n\n<h2 id=\"another-header\">Another header</h2>\n",
+
+		"   Header\n======\n",
+		"<h1 id=\"header\">Header</h1>\n",
+
+		"Header with *inline*\n=====\n",
+		"<h1 id=\"header-with-inline\">Header with <em>inline</em></h1>\n",
+
+		"Paragraph\n\n\n\n\nHeader\n===\n",
+		"<p>Paragraph</p>\n\n<h1 id=\"header\">Header</h1>\n",
+
+		"Trailing space \n====        \n\n",
+		"<h1 id=\"trailing-space\">Trailing space</h1>\n",
+
+		"Trailing spaces\n====        \n\n",
+		"<h1 id=\"trailing-spaces\">Trailing spaces</h1>\n",
+
+		"Double underline\n=====\n=====\n",
+		"<h1 id=\"double-underline\">Double underline</h1>\n\n<p>=====</p>\n",
+
+		"Header\n======\n\nHeader\n======\n",
+		"<h1 id=\"header\">Header</h1>\n\n<h1 id=\"header-1\">Header</h1>\n",
+
+		"Header 1\n========\n\nHeader 1\n========\n",
+		"<h1 id=\"header-1\">Header 1</h1>\n\n<h1 id=\"header-1-1\">Header 1</h1>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_AUTO_HEADER_IDS)
+}
+
+func TestHorizontalRule(t *testing.T) {
+	var tests = []string{
+		"-\n",
+		"<p>-</p>\n",
+
+		"--\n",
+		"<p>--</p>\n",
+
+		"---\n",
+		"<hr />\n",
+
+		"----\n",
+		"<hr />\n",
+
+		"*\n",
+		"<p>*</p>\n",
+
+		"**\n",
+		"<p>**</p>\n",
+
+		"***\n",
+		"<hr />\n",
+
+		"****\n",
+		"<hr />\n",
+
+		"_\n",
+		"<p>_</p>\n",
+
+		"__\n",
+		"<p>__</p>\n",
+
+		"___\n",
+		"<hr />\n",
+
+		"____\n",
+		"<hr />\n",
+
+		"-*-\n",
+		"<p>-*-</p>\n",
+
+		"- - -\n",
+		"<hr />\n",
+
+		"* * *\n",
+		"<hr />\n",
+
+		"_ _ _\n",
+		"<hr />\n",
+
+		"-----*\n",
+		"<p>-----*</p>\n",
+
+		"   ------   \n",
+		"<hr />\n",
+
+		"Hello\n***\n",
+		"<p>Hello</p>\n\n<hr />\n",
+
+		"---\n***\n___\n",
+		"<hr />\n\n<hr />\n\n<hr />\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestUnorderedList(t *testing.T) {
+	var tests = []string{
+		"* Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"* Yin\n* Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"* Ting\n* Bong\n* Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"* Yin\n\n* Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"* Ting\n\n* Bong\n* Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"+ Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"+ Yin\n+ Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"+ Ting\n+ Bong\n+ Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"+ Yin\n\n+ Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"+ Ting\n\n+ Bong\n+ Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"- Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"- Yin\n- Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"- Ting\n- Bong\n- Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"- Yin\n\n- Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"- Ting\n\n- Bong\n- Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"*Hello\n",
+		"<p>*Hello</p>\n",
+
+		"*   Hello \n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"*   Hello \n    Next line \n",
+		"<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
+
+		"Paragraph\n* No linebreak\n",
+		"<p>Paragraph\n* No linebreak</p>\n",
+
+		"Paragraph\n\n* Linebreak\n",
+		"<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n",
+		"<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n\n    * Nested list\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n    Second line\n\n    + Nested\n",
+		"<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n    + Nested\n\n    Continued\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
+
+		"*   List\n   * shallow indent\n",
+		"<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
+
+		"* List\n" +
+			" * shallow indent\n" +
+			"  * part of second list\n" +
+			"   * still second\n" +
+			"    * almost there\n" +
+			"     * third level\n",
+		"<ul>\n" +
+			"<li>List\n\n" +
+			"<ul>\n" +
+			"<li>shallow indent</li>\n" +
+			"<li>part of second list</li>\n" +
+			"<li>still second</li>\n" +
+			"<li>almost there\n\n" +
+			"<ul>\n" +
+			"<li>third level</li>\n" +
+			"</ul></li>\n" +
+			"</ul></li>\n" +
+			"</ul>\n",
+
+		"* List\n        extra indent, same paragraph\n",
+		"<ul>\n<li>List\n    extra indent, same paragraph</li>\n</ul>\n",
+
+		"* List\n\n        code block\n",
+		"<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
+
+		"* List\n\n          code block with spaces\n",
+		"<ul>\n<li><p>List</p>\n\n<pre><code>  code block with spaces\n</code></pre></li>\n</ul>\n",
+
+		"* List\n\n    * sublist\n\n    normal text\n\n    * another sublist\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>sublist</li>\n</ul>\n\n<p>normal text</p>\n\n<ul>\n<li>another sublist</li>\n</ul></li>\n</ul>\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestOrderedList(t *testing.T) {
+	var tests = []string{
+		"1. Hello\n",
+		"<ol>\n<li>Hello</li>\n</ol>\n",
+
+		"1. Yin\n2. Yang\n",
+		"<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
+
+		"1. Ting\n2. Bong\n3. Goo\n",
+		"<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
+
+		"1. Yin\n\n2. Yang\n",
+		"<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
+
+		"1. Ting\n\n2. Bong\n3. Goo\n",
+		"<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
+
+		"1 Hello\n",
+		"<p>1 Hello</p>\n",
+
+		"1.Hello\n",
+		"<p>1.Hello</p>\n",
+
+		"1.  Hello \n",
+		"<ol>\n<li>Hello</li>\n</ol>\n",
+
+		"1.  Hello \n    Next line \n",
+		"<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
+
+		"Paragraph\n1. No linebreak\n",
+		"<p>Paragraph\n1. No linebreak</p>\n",
+
+		"Paragraph\n\n1. Linebreak\n",
+		"<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
+
+		"1.  List\n    1. Nested list\n",
+		"<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n\n    1. Nested list\n",
+		"<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n    Second line\n\n    1. Nested\n",
+		"<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n    1. Nested\n\n    Continued\n",
+		"<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
+
+		"1.  List\n   1. shallow indent\n",
+		"<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
+
+		"1. List\n" +
+			" 1. shallow indent\n" +
+			"  2. part of second list\n" +
+			"   3. still second\n" +
+			"    4. almost there\n" +
+			"     1. third level\n",
+		"<ol>\n" +
+			"<li>List\n\n" +
+			"<ol>\n" +
+			"<li>shallow indent</li>\n" +
+			"<li>part of second list</li>\n" +
+			"<li>still second</li>\n" +
+			"<li>almost there\n\n" +
+			"<ol>\n" +
+			"<li>third level</li>\n" +
+			"</ol></li>\n" +
+			"</ol></li>\n" +
+			"</ol>\n",
+
+		"1. List\n        extra indent, same paragraph\n",
+		"<ol>\n<li>List\n    extra indent, same paragraph</li>\n</ol>\n",
+
+		"1. List\n\n        code block\n",
+		"<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
+
+		"1. List\n\n          code block with spaces\n",
+		"<ol>\n<li><p>List</p>\n\n<pre><code>  code block with spaces\n</code></pre></li>\n</ol>\n",
+
+		"1. List\n    * Mixted list\n",
+		"<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
+
+		"1. List\n * Mixed list\n",
+		"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
+
+		"* Start with unordered\n 1. Ordered\n",
+		"<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
+
+		"* Start with unordered\n    1. Ordered\n",
+		"<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
+
+		"1. numbers\n1. are ignored\n",
+		"<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestPreformattedHtml(t *testing.T) {
+	var tests = []string{
+		"<div></div>\n",
+		"<div></div>\n",
+
+		"<div>\n</div>\n",
+		"<div>\n</div>\n",
+
+		"<div>\n</div>\nParagraph\n",
+		"<p><div>\n</div>\nParagraph</p>\n",
+
+		"<div class=\"foo\">\n</div>\n",
+		"<div class=\"foo\">\n</div>\n",
+
+		"<div>\nAnything here\n</div>\n",
+		"<div>\nAnything here\n</div>\n",
+
+		"<div>\n  Anything here\n</div>\n",
+		"<div>\n  Anything here\n</div>\n",
+
+		"<div>\nAnything here\n  </div>\n",
+		"<div>\nAnything here\n  </div>\n",
+
+		"<div>\nThis is *not* &proceessed\n</div>\n",
+		"<div>\nThis is *not* &proceessed\n</div>\n",
+
+		"<faketag>\n  Something\n</faketag>\n",
+		"<p><faketag>\n  Something\n</faketag></p>\n",
+
+		"<div>\n  Something here\n</divv>\n",
+		"<p><div>\n  Something here\n</divv></p>\n",
+
+		"Paragraph\n<div>\nHere? >&<\n</div>\n",
+		"<p>Paragraph\n<div>\nHere? &gt;&amp;&lt;\n</div></p>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
+		"<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
+
+		"Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
+		"<p>Paragraph\n<div>\nHere? &gt;&amp;&lt;\n</div>\nAnd here?</p>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<p><div>\nHow about here? &gt;&amp;&lt;\n</div>\nAnd here?</p>\n",
+
+		"Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
+		"<p>Paragraph\n<div>\nHere? &gt;&amp;&lt;\n</div></p>\n\n<p>And here?</p>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
+	}
+	doTestsBlock(t, tests, 0)
+}
+
+func TestPreformattedHtmlLax(t *testing.T) {
+	var tests = []string{
+		"Paragraph\n<div>\nHere? >&<\n</div>\n",
+		"<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\n",
+		"<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n",
+
+		"Paragraph\n<div>\nHere? >&<\n</div>\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
+
+		"Paragraph\n<div>\nHere? >&<\n</div>\n\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<div>\nHere? >&<\n</div>\n\n<p>And here?</p>\n",
+
+		"Paragraph\n\n<div>\nHow about here? >&<\n</div>\n\nAnd here?\n",
+		"<p>Paragraph</p>\n\n<div>\nHow about here? >&<\n</div>\n\n<p>And here?</p>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_LAX_HTML_BLOCKS)
+}
+
+func TestFencedCodeBlock(t *testing.T) {
+	var tests = []string{
+		"``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
+		"<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
+
+		"``` c\n/* special & char < > \" escaping */\n```\n",
+		"<pre><code class=\"language-c\">/* special &amp; char &lt; &gt; &quot; escaping */\n</code></pre>\n",
+
+		"``` c\nno *inline* processing ~~of text~~\n```\n",
+		"<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
+
+		"```\nNo language\n```\n",
+		"<pre><code>No language\n</code></pre>\n",
+
+		"``` {ocaml}\nlanguage in braces\n```\n",
+		"<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
+
+		"```    {ocaml}      \nwith extra whitespace\n```\n",
+		"<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
+
+		"```{   ocaml   }\nwith extra whitespace\n```\n",
+		"<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
+
+		"~ ~~ java\nWith whitespace\n~~~\n",
+		"<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
+
+		"~~\nonly two\n~~\n",
+		"<p>~~\nonly two\n~~</p>\n",
+
+		"```` python\nextra\n````\n",
+		"<pre><code class=\"language-python\">extra\n</code></pre>\n",
+
+		"~~~ perl\nthree to start, four to end\n~~~~\n",
+		"<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
+
+		"~~~~ perl\nfour to start, three to end\n~~~\n",
+		"<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
+
+		"~~~ bash\ntildes\n~~~\n",
+		"<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
+
+		"``` lisp\nno ending\n",
+		"<p>``` lisp\nno ending</p>\n",
+
+		"~~~ lisp\nend with language\n~~~ lisp\n",
+		"<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
+
+		"```\nmismatched begin and end\n~~~\n",
+		"<p>```\nmismatched begin and end\n~~~</p>\n",
+
+		"~~~\nmismatched begin and end\n```\n",
+		"<p>~~~\nmismatched begin and end\n```</p>\n",
+
+		"   ``` oz\nleading spaces\n```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"  ``` oz\nleading spaces\n ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		" ``` oz\nleading spaces\n  ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"``` oz\nleading spaces\n   ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"    ``` oz\nleading spaces\n    ```\n",
+		"<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces\n    ```</p>\n",
+
+		"Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n",
+		"<p>Bla bla</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Bla Bla</p>\n",
+
+		"Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nAnd some text after a fenced code block",
+		"<p>Some text before a fenced code block</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>And some text after a fenced code block</p>\n",
+
+		"`",
+		"<p>`</p>\n",
+
+		"Bla bla\n\n``` oz\ncode blocks breakup paragraphs\n```\n\nBla Bla\n\n``` oz\nmultiple code blocks work okay\n```\n\nBla Bla\n",
+		"<p>Bla bla</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Bla Bla</p>\n\n<pre><code class=\"language-oz\">multiple code blocks work okay\n</code></pre>\n\n<p>Bla Bla</p>\n",
+
+		"Some text before a fenced code block\n``` oz\ncode blocks breakup paragraphs\n```\nSome text in between\n``` oz\nmultiple code blocks work okay\n```\nAnd some text after a fenced code block",
+		"<p>Some text before a fenced code block</p>\n\n<pre><code class=\"language-oz\">code blocks breakup paragraphs\n</code></pre>\n\n<p>Some text in between</p>\n\n<pre><code class=\"language-oz\">multiple code blocks work okay\n</code></pre>\n\n<p>And some text after a fenced code block</p>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_FENCED_CODE)
+}
+
+func TestTable(t *testing.T) {
+	var tests = []string{
+		"a | b\n---|---\nc | d\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td>c</td>\n<td>d</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a | b\n---|--\nc | d\n",
+		"<p>a | b\n---|--\nc | d</p>\n",
+
+		"|a|b|c|d|\n|----|----|----|---|\n|e|f|g|h|\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td>e</td>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"*a*|__b__|[c](C)|d\n---|---|---|---\ne|f|g|h\n",
+		"<table>\n<thead>\n<tr>\n<th><em>a</em></th>\n<th><strong>b</strong></th>\n<th><a href=\"C\">c</a></th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td>e</td>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a|b|c\n---|---|---\nd|e|f\ng|h\ni|j|k|l|m\nn|o|p\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td>d</td>\n<td>e</td>\n<td>f</td>\n</tr>\n\n" +
+			"<tr>\n<td>g</td>\n<td>h</td>\n<td></td>\n</tr>\n\n" +
+			"<tr>\n<td>i</td>\n<td>j</td>\n<td>k</td>\n</tr>\n\n" +
+			"<tr>\n<td>n</td>\n<td>o</td>\n<td>p</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a|b|c\n---|---|---\n*d*|__e__|f\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td><em>d</em></td>\n<td><strong>e</strong></td>\n<td>f</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a|b|c|d\n:--|--:|:-:|---\ne|f|g|h\n",
+		"<table>\n<thead>\n<tr>\n<th align=\"left\">a</th>\n<th align=\"right\">b</th>\n" +
+			"<th align=\"center\">c</th>\n<th>d</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td align=\"left\">e</td>\n<td align=\"right\">f</td>\n" +
+			"<td align=\"center\">g</td>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a|b|c\n---|---|---\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n</tr>\n</thead>\n\n<tbody>\n</tbody>\n</table>\n",
+
+		"a| b|c | d | e\n---|---|---|---|---\nf| g|h | i |j\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b</th>\n<th>c</th>\n<th>d</th>\n<th>e</th>\n</tr>\n</thead>\n\n" +
+			"<tbody>\n<tr>\n<td>f</td>\n<td>g</td>\n<td>h</td>\n<td>i</td>\n<td>j</td>\n</tr>\n</tbody>\n</table>\n",
+
+		"a|b\\|c|d\n---|---|---\nf|g\\|h|i\n",
+		"<table>\n<thead>\n<tr>\n<th>a</th>\n<th>b|c</th>\n<th>d</th>\n</tr>\n</thead>\n\n<tbody>\n<tr>\n<td>f</td>\n<td>g|h</td>\n<td>i</td>\n</tr>\n</tbody>\n</table>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_TABLES)
+}
+
+func TestUnorderedListWith_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+	var tests = []string{
+		"* Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"* Yin\n* Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"* Ting\n* Bong\n* Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"* Yin\n\n* Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"* Ting\n\n* Bong\n* Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"+ Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"+ Yin\n+ Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"+ Ting\n+ Bong\n+ Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"+ Yin\n\n+ Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"+ Ting\n\n+ Bong\n+ Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"- Hello\n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"- Yin\n- Yang\n",
+		"<ul>\n<li>Yin</li>\n<li>Yang</li>\n</ul>\n",
+
+		"- Ting\n- Bong\n- Goo\n",
+		"<ul>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ul>\n",
+
+		"- Yin\n\n- Yang\n",
+		"<ul>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ul>\n",
+
+		"- Ting\n\n- Bong\n- Goo\n",
+		"<ul>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ul>\n",
+
+		"*Hello\n",
+		"<p>*Hello</p>\n",
+
+		"*   Hello \n",
+		"<ul>\n<li>Hello</li>\n</ul>\n",
+
+		"*   Hello \n    Next line \n",
+		"<ul>\n<li>Hello\nNext line</li>\n</ul>\n",
+
+		"Paragraph\n* No linebreak\n",
+		"<p>Paragraph</p>\n\n<ul>\n<li>No linebreak</li>\n</ul>\n",
+
+		"Paragraph\n\n* Linebreak\n",
+		"<p>Paragraph</p>\n\n<ul>\n<li>Linebreak</li>\n</ul>\n",
+
+		"*   List\n    * Nested list\n",
+		"<ul>\n<li>List\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n\n    * Nested list\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested list</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n    Second line\n\n    + Nested\n",
+		"<ul>\n<li><p>List\nSecond line</p>\n\n<ul>\n<li>Nested</li>\n</ul></li>\n</ul>\n",
+
+		"*   List\n    + Nested\n\n    Continued\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>Nested</li>\n</ul>\n\n<p>Continued</p></li>\n</ul>\n",
+
+		"*   List\n   * shallow indent\n",
+		"<ul>\n<li>List\n\n<ul>\n<li>shallow indent</li>\n</ul></li>\n</ul>\n",
+
+		"* List\n" +
+			" * shallow indent\n" +
+			"  * part of second list\n" +
+			"   * still second\n" +
+			"    * almost there\n" +
+			"     * third level\n",
+		"<ul>\n" +
+			"<li>List\n\n" +
+			"<ul>\n" +
+			"<li>shallow indent</li>\n" +
+			"<li>part of second list</li>\n" +
+			"<li>still second</li>\n" +
+			"<li>almost there\n\n" +
+			"<ul>\n" +
+			"<li>third level</li>\n" +
+			"</ul></li>\n" +
+			"</ul></li>\n" +
+			"</ul>\n",
+
+		"* List\n        extra indent, same paragraph\n",
+		"<ul>\n<li>List\n    extra indent, same paragraph</li>\n</ul>\n",
+
+		"* List\n\n        code block\n",
+		"<ul>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ul>\n",
+
+		"* List\n\n          code block with spaces\n",
+		"<ul>\n<li><p>List</p>\n\n<pre><code>  code block with spaces\n</code></pre></li>\n</ul>\n",
+
+		"* List\n\n    * sublist\n\n    normal text\n\n    * another sublist\n",
+		"<ul>\n<li><p>List</p>\n\n<ul>\n<li>sublist</li>\n</ul>\n\n<p>normal text</p>\n\n<ul>\n<li>another sublist</li>\n</ul></li>\n</ul>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestOrderedList_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+	var tests = []string{
+		"1. Hello\n",
+		"<ol>\n<li>Hello</li>\n</ol>\n",
+
+		"1. Yin\n2. Yang\n",
+		"<ol>\n<li>Yin</li>\n<li>Yang</li>\n</ol>\n",
+
+		"1. Ting\n2. Bong\n3. Goo\n",
+		"<ol>\n<li>Ting</li>\n<li>Bong</li>\n<li>Goo</li>\n</ol>\n",
+
+		"1. Yin\n\n2. Yang\n",
+		"<ol>\n<li><p>Yin</p></li>\n\n<li><p>Yang</p></li>\n</ol>\n",
+
+		"1. Ting\n\n2. Bong\n3. Goo\n",
+		"<ol>\n<li><p>Ting</p></li>\n\n<li><p>Bong</p></li>\n\n<li><p>Goo</p></li>\n</ol>\n",
+
+		"1 Hello\n",
+		"<p>1 Hello</p>\n",
+
+		"1.Hello\n",
+		"<p>1.Hello</p>\n",
+
+		"1.  Hello \n",
+		"<ol>\n<li>Hello</li>\n</ol>\n",
+
+		"1.  Hello \n    Next line \n",
+		"<ol>\n<li>Hello\nNext line</li>\n</ol>\n",
+
+		"Paragraph\n1. No linebreak\n",
+		"<p>Paragraph</p>\n\n<ol>\n<li>No linebreak</li>\n</ol>\n",
+
+		"Paragraph\n\n1. Linebreak\n",
+		"<p>Paragraph</p>\n\n<ol>\n<li>Linebreak</li>\n</ol>\n",
+
+		"1.  List\n    1. Nested list\n",
+		"<ol>\n<li>List\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n\n    1. Nested list\n",
+		"<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested list</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n    Second line\n\n    1. Nested\n",
+		"<ol>\n<li><p>List\nSecond line</p>\n\n<ol>\n<li>Nested</li>\n</ol></li>\n</ol>\n",
+
+		"1.  List\n    1. Nested\n\n    Continued\n",
+		"<ol>\n<li><p>List</p>\n\n<ol>\n<li>Nested</li>\n</ol>\n\n<p>Continued</p></li>\n</ol>\n",
+
+		"1.  List\n   1. shallow indent\n",
+		"<ol>\n<li>List\n\n<ol>\n<li>shallow indent</li>\n</ol></li>\n</ol>\n",
+
+		"1. List\n" +
+			" 1. shallow indent\n" +
+			"  2. part of second list\n" +
+			"   3. still second\n" +
+			"    4. almost there\n" +
+			"     1. third level\n",
+		"<ol>\n" +
+			"<li>List\n\n" +
+			"<ol>\n" +
+			"<li>shallow indent</li>\n" +
+			"<li>part of second list</li>\n" +
+			"<li>still second</li>\n" +
+			"<li>almost there\n\n" +
+			"<ol>\n" +
+			"<li>third level</li>\n" +
+			"</ol></li>\n" +
+			"</ol></li>\n" +
+			"</ol>\n",
+
+		"1. List\n        extra indent, same paragraph\n",
+		"<ol>\n<li>List\n    extra indent, same paragraph</li>\n</ol>\n",
+
+		"1. List\n\n        code block\n",
+		"<ol>\n<li><p>List</p>\n\n<pre><code>code block\n</code></pre></li>\n</ol>\n",
+
+		"1. List\n\n          code block with spaces\n",
+		"<ol>\n<li><p>List</p>\n\n<pre><code>  code block with spaces\n</code></pre></li>\n</ol>\n",
+
+		"1. List\n    * Mixted list\n",
+		"<ol>\n<li>List\n\n<ul>\n<li>Mixted list</li>\n</ul></li>\n</ol>\n",
+
+		"1. List\n * Mixed list\n",
+		"<ol>\n<li>List\n\n<ul>\n<li>Mixed list</li>\n</ul></li>\n</ol>\n",
+
+		"* Start with unordered\n 1. Ordered\n",
+		"<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
+
+		"* Start with unordered\n    1. Ordered\n",
+		"<ul>\n<li>Start with unordered\n\n<ol>\n<li>Ordered</li>\n</ol></li>\n</ul>\n",
+
+		"1. numbers\n1. are ignored\n",
+		"<ol>\n<li>numbers</li>\n<li>are ignored</li>\n</ol>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestFencedCodeBlock_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+	var tests = []string{
+		"``` go\nfunc foo() bool {\n\treturn true;\n}\n```\n",
+		"<pre><code class=\"language-go\">func foo() bool {\n\treturn true;\n}\n</code></pre>\n",
+
+		"``` c\n/* special & char < > \" escaping */\n```\n",
+		"<pre><code class=\"language-c\">/* special &amp; char &lt; &gt; &quot; escaping */\n</code></pre>\n",
+
+		"``` c\nno *inline* processing ~~of text~~\n```\n",
+		"<pre><code class=\"language-c\">no *inline* processing ~~of text~~\n</code></pre>\n",
+
+		"```\nNo language\n```\n",
+		"<pre><code>No language\n</code></pre>\n",
+
+		"``` {ocaml}\nlanguage in braces\n```\n",
+		"<pre><code class=\"language-ocaml\">language in braces\n</code></pre>\n",
+
+		"```    {ocaml}      \nwith extra whitespace\n```\n",
+		"<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
+
+		"```{   ocaml   }\nwith extra whitespace\n```\n",
+		"<pre><code class=\"language-ocaml\">with extra whitespace\n</code></pre>\n",
+
+		"~ ~~ java\nWith whitespace\n~~~\n",
+		"<p>~ ~~ java\nWith whitespace\n~~~</p>\n",
+
+		"~~\nonly two\n~~\n",
+		"<p>~~\nonly two\n~~</p>\n",
+
+		"```` python\nextra\n````\n",
+		"<pre><code class=\"language-python\">extra\n</code></pre>\n",
+
+		"~~~ perl\nthree to start, four to end\n~~~~\n",
+		"<p>~~~ perl\nthree to start, four to end\n~~~~</p>\n",
+
+		"~~~~ perl\nfour to start, three to end\n~~~\n",
+		"<p>~~~~ perl\nfour to start, three to end\n~~~</p>\n",
+
+		"~~~ bash\ntildes\n~~~\n",
+		"<pre><code class=\"language-bash\">tildes\n</code></pre>\n",
+
+		"``` lisp\nno ending\n",
+		"<p>``` lisp\nno ending</p>\n",
+
+		"~~~ lisp\nend with language\n~~~ lisp\n",
+		"<p>~~~ lisp\nend with language\n~~~ lisp</p>\n",
+
+		"```\nmismatched begin and end\n~~~\n",
+		"<p>```\nmismatched begin and end\n~~~</p>\n",
+
+		"~~~\nmismatched begin and end\n```\n",
+		"<p>~~~\nmismatched begin and end\n```</p>\n",
+
+		"   ``` oz\nleading spaces\n```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"  ``` oz\nleading spaces\n ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		" ``` oz\nleading spaces\n  ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"``` oz\nleading spaces\n   ```\n",
+		"<pre><code class=\"language-oz\">leading spaces\n</code></pre>\n",
+
+		"    ``` oz\nleading spaces\n    ```\n",
+		"<pre><code>``` oz\n</code></pre>\n\n<p>leading spaces</p>\n\n<pre><code>```\n</code></pre>\n",
+	}
+	doTestsBlock(t, tests, EXTENSION_FENCED_CODE|EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
+
+func TestTitleBlock_EXTENSION_TITLEBLOCK(t *testing.T) {
+	var tests = []string{
+		"% Some title\n" +
+			"% Another title line\n" +
+			"% Yep, more here too\n",
+		"<h1 class=\"title\">" +
+			"Some title\n" +
+			"Another title line\n" +
+			"Yep, more here too\n" +
+			"</h1>",
+	}
+
+	doTestsBlock(t, tests, EXTENSION_TITLEBLOCK)
+
+}
diff --git a/vendor/src/github.com/russross/blackfriday/html.go b/vendor/src/github.com/russross/blackfriday/html.go
new file mode 100644
index 0000000..3655a10
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/html.go
@@ -0,0 +1,922 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+//
+// HTML rendering backend
+//
+//
+
+package blackfriday
+
+import (
+	"bytes"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+)
+
+// Html renderer configuration options.
+const (
+	HTML_SKIP_HTML                 = 1 << iota // skip preformatted HTML blocks
+	HTML_SKIP_STYLE                            // skip embedded <style> elements
+	HTML_SKIP_IMAGES                           // skip embedded images
+	HTML_SKIP_LINKS                            // skip all links
+	HTML_SAFELINK                              // only link to trusted protocols
+	HTML_NOFOLLOW_LINKS                        // only link with rel="nofollow"
+	HTML_NOREFERRER_LINKS                      // only link with rel="noreferrer"
+	HTML_HREF_TARGET_BLANK                     // add a blank target
+	HTML_TOC                                   // generate a table of contents
+	HTML_OMIT_CONTENTS                         // skip the main contents (for a standalone table of contents)
+	HTML_COMPLETE_PAGE                         // generate a complete HTML page
+	HTML_USE_XHTML                             // generate XHTML output instead of HTML
+	HTML_USE_SMARTYPANTS                       // enable smart punctuation substitutions
+	HTML_SMARTYPANTS_FRACTIONS                 // enable smart fractions (with HTML_USE_SMARTYPANTS)
+	HTML_SMARTYPANTS_LATEX_DASHES              // enable LaTeX-style dashes (with HTML_USE_SMARTYPANTS)
+	HTML_SMARTYPANTS_ANGLED_QUOTES             // enable angled double quotes (with HTML_USE_SMARTYPANTS) for double quotes rendering
+	HTML_FOOTNOTE_RETURN_LINKS                 // generate a link at the end of a footnote to return to the source
+)
+
+var (
+	alignments = []string{
+		"left",
+		"right",
+		"center",
+	}
+
+	// TODO: improve this regexp to catch all possible entities:
+	htmlEntity = regexp.MustCompile(`&[a-z]{2,5};`)
+)
+
+type HtmlRendererParameters struct {
+	// Prepend this text to each relative URL.
+	AbsolutePrefix string
+	// Add this text to each footnote anchor, to ensure uniqueness.
+	FootnoteAnchorPrefix string
+	// Show this text inside the <a> tag for a footnote return link, if the
+	// HTML_FOOTNOTE_RETURN_LINKS flag is enabled. If blank, the string
+	// <sup>[return]</sup> is used.
+	FootnoteReturnLinkContents string
+	// If set, add this text to the front of each Header ID, to ensure
+	// uniqueness.
+	HeaderIDPrefix string
+	// If set, add this text to the back of each Header ID, to ensure uniqueness.
+	HeaderIDSuffix string
+}
+
+// Html is a type that implements the Renderer interface for HTML output.
+//
+// Do not create this directly, instead use the HtmlRenderer function.
+type Html struct {
+	flags    int    // HTML_* options
+	closeTag string // how to end singleton tags: either " />\n" or ">\n"
+	title    string // document title
+	css      string // optional css file url (used with HTML_COMPLETE_PAGE)
+
+	parameters HtmlRendererParameters
+
+	// table of contents data
+	tocMarker    int
+	headerCount  int
+	currentLevel int
+	toc          *bytes.Buffer
+
+	// Track header IDs to prevent ID collision in a single generation.
+	headerIDs map[string]int
+
+	smartypants *smartypantsRenderer
+}
+
+const (
+	xhtmlClose = " />\n"
+	htmlClose  = ">\n"
+)
+
+// HtmlRenderer creates and configures an Html object, which
+// satisfies the Renderer interface.
+//
+// flags is a set of HTML_* options ORed together.
+// title is the title of the document, and css is a URL for the document's
+// stylesheet.
+// title and css are only used when HTML_COMPLETE_PAGE is selected.
+func HtmlRenderer(flags int, title string, css string) Renderer {
+	return HtmlRendererWithParameters(flags, title, css, HtmlRendererParameters{})
+}
+
+func HtmlRendererWithParameters(flags int, title string,
+	css string, renderParameters HtmlRendererParameters) Renderer {
+	// configure the rendering engine
+	closeTag := htmlClose
+	if flags&HTML_USE_XHTML != 0 {
+		closeTag = xhtmlClose
+	}
+
+	if renderParameters.FootnoteReturnLinkContents == "" {
+		renderParameters.FootnoteReturnLinkContents = `<sup>[return]</sup>`
+	}
+
+	return &Html{
+		flags:      flags,
+		closeTag:   closeTag,
+		title:      title,
+		css:        css,
+		parameters: renderParameters,
+
+		headerCount:  0,
+		currentLevel: 0,
+		toc:          new(bytes.Buffer),
+
+		headerIDs: make(map[string]int),
+
+		smartypants: smartypants(flags),
+	}
+}
+
+// Using if statements is a bit faster than a switch statement. As the compiler
+// improves, this should be unnecessary this is only worthwhile because
+// attrEscape is the single largest CPU user in normal use.
+// Also tried using map, but that gave a ~3x slowdown.
+func escapeSingleChar(char byte) (string, bool) {
+	if char == '"' {
+		return "&quot;", true
+	}
+	if char == '&' {
+		return "&amp;", true
+	}
+	if char == '<' {
+		return "&lt;", true
+	}
+	if char == '>' {
+		return "&gt;", true
+	}
+	return "", false
+}
+
+func attrEscape(out *bytes.Buffer, src []byte) {
+	org := 0
+	for i, ch := range src {
+		if entity, ok := escapeSingleChar(ch); ok {
+			if i > org {
+				// copy all the normal characters since the last escape
+				out.Write(src[org:i])
+			}
+			org = i + 1
+			out.WriteString(entity)
+		}
+	}
+	if org < len(src) {
+		out.Write(src[org:])
+	}
+}
+
+func entityEscapeWithSkip(out *bytes.Buffer, src []byte, skipRanges [][]int) {
+	end := 0
+	for _, rang := range skipRanges {
+		attrEscape(out, src[end:rang[0]])
+		out.Write(src[rang[0]:rang[1]])
+		end = rang[1]
+	}
+	attrEscape(out, src[end:])
+}
+
+func (options *Html) GetFlags() int {
+	return options.flags
+}
+
+func (options *Html) TitleBlock(out *bytes.Buffer, text []byte) {
+	text = bytes.TrimPrefix(text, []byte("% "))
+	text = bytes.Replace(text, []byte("\n% "), []byte("\n"), -1)
+	out.WriteString("<h1 class=\"title\">")
+	out.Write(text)
+	out.WriteString("\n</h1>")
+}
+
+func (options *Html) Header(out *bytes.Buffer, text func() bool, level int, id string) {
+	marker := out.Len()
+	doubleSpace(out)
+
+	if id == "" && options.flags&HTML_TOC != 0 {
+		id = fmt.Sprintf("toc_%d", options.headerCount)
+	}
+
+	if id != "" {
+		id = options.ensureUniqueHeaderID(id)
+
+		if options.parameters.HeaderIDPrefix != "" {
+			id = options.parameters.HeaderIDPrefix + id
+		}
+
+		if options.parameters.HeaderIDSuffix != "" {
+			id = id + options.parameters.HeaderIDSuffix
+		}
+
+		out.WriteString(fmt.Sprintf("<h%d id=\"%s\">", level, id))
+	} else {
+		out.WriteString(fmt.Sprintf("<h%d>", level))
+	}
+
+	tocMarker := out.Len()
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+
+	// are we building a table of contents?
+	if options.flags&HTML_TOC != 0 {
+		options.TocHeaderWithAnchor(out.Bytes()[tocMarker:], level, id)
+	}
+
+	out.WriteString(fmt.Sprintf("</h%d>\n", level))
+}
+
+func (options *Html) BlockHtml(out *bytes.Buffer, text []byte) {
+	if options.flags&HTML_SKIP_HTML != 0 {
+		return
+	}
+
+	doubleSpace(out)
+	out.Write(text)
+	out.WriteByte('\n')
+}
+
+func (options *Html) HRule(out *bytes.Buffer) {
+	doubleSpace(out)
+	out.WriteString("<hr")
+	out.WriteString(options.closeTag)
+}
+
+func (options *Html) BlockCode(out *bytes.Buffer, text []byte, lang string) {
+	doubleSpace(out)
+
+	// parse out the language names/classes
+	count := 0
+	for _, elt := range strings.Fields(lang) {
+		if elt[0] == '.' {
+			elt = elt[1:]
+		}
+		if len(elt) == 0 {
+			continue
+		}
+		if count == 0 {
+			out.WriteString("<pre><code class=\"language-")
+		} else {
+			out.WriteByte(' ')
+		}
+		attrEscape(out, []byte(elt))
+		count++
+	}
+
+	if count == 0 {
+		out.WriteString("<pre><code>")
+	} else {
+		out.WriteString("\">")
+	}
+
+	attrEscape(out, text)
+	out.WriteString("</code></pre>\n")
+}
+
+func (options *Html) BlockQuote(out *bytes.Buffer, text []byte) {
+	doubleSpace(out)
+	out.WriteString("<blockquote>\n")
+	out.Write(text)
+	out.WriteString("</blockquote>\n")
+}
+
+func (options *Html) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
+	doubleSpace(out)
+	out.WriteString("<table>\n<thead>\n")
+	out.Write(header)
+	out.WriteString("</thead>\n\n<tbody>\n")
+	out.Write(body)
+	out.WriteString("</tbody>\n</table>\n")
+}
+
+func (options *Html) TableRow(out *bytes.Buffer, text []byte) {
+	doubleSpace(out)
+	out.WriteString("<tr>\n")
+	out.Write(text)
+	out.WriteString("\n</tr>\n")
+}
+
+func (options *Html) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
+	doubleSpace(out)
+	switch align {
+	case TABLE_ALIGNMENT_LEFT:
+		out.WriteString("<th align=\"left\">")
+	case TABLE_ALIGNMENT_RIGHT:
+		out.WriteString("<th align=\"right\">")
+	case TABLE_ALIGNMENT_CENTER:
+		out.WriteString("<th align=\"center\">")
+	default:
+		out.WriteString("<th>")
+	}
+
+	out.Write(text)
+	out.WriteString("</th>")
+}
+
+func (options *Html) TableCell(out *bytes.Buffer, text []byte, align int) {
+	doubleSpace(out)
+	switch align {
+	case TABLE_ALIGNMENT_LEFT:
+		out.WriteString("<td align=\"left\">")
+	case TABLE_ALIGNMENT_RIGHT:
+		out.WriteString("<td align=\"right\">")
+	case TABLE_ALIGNMENT_CENTER:
+		out.WriteString("<td align=\"center\">")
+	default:
+		out.WriteString("<td>")
+	}
+
+	out.Write(text)
+	out.WriteString("</td>")
+}
+
+func (options *Html) Footnotes(out *bytes.Buffer, text func() bool) {
+	out.WriteString("<div class=\"footnotes\">\n")
+	options.HRule(out)
+	options.List(out, text, LIST_TYPE_ORDERED)
+	out.WriteString("</div>\n")
+}
+
+func (options *Html) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
+	if flags&LIST_ITEM_CONTAINS_BLOCK != 0 || flags&LIST_ITEM_BEGINNING_OF_LIST != 0 {
+		doubleSpace(out)
+	}
+	slug := slugify(name)
+	out.WriteString(`<li id="`)
+	out.WriteString(`fn:`)
+	out.WriteString(options.parameters.FootnoteAnchorPrefix)
+	out.Write(slug)
+	out.WriteString(`">`)
+	out.Write(text)
+	if options.flags&HTML_FOOTNOTE_RETURN_LINKS != 0 {
+		out.WriteString(` <a class="footnote-return" href="#`)
+		out.WriteString(`fnref:`)
+		out.WriteString(options.parameters.FootnoteAnchorPrefix)
+		out.Write(slug)
+		out.WriteString(`">`)
+		out.WriteString(options.parameters.FootnoteReturnLinkContents)
+		out.WriteString(`</a>`)
+	}
+	out.WriteString("</li>\n")
+}
+
+func (options *Html) List(out *bytes.Buffer, text func() bool, flags int) {
+	marker := out.Len()
+	doubleSpace(out)
+
+	if flags&LIST_TYPE_ORDERED != 0 {
+		out.WriteString("<ol>")
+	} else {
+		out.WriteString("<ul>")
+	}
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	if flags&LIST_TYPE_ORDERED != 0 {
+		out.WriteString("</ol>\n")
+	} else {
+		out.WriteString("</ul>\n")
+	}
+}
+
+func (options *Html) ListItem(out *bytes.Buffer, text []byte, flags int) {
+	if flags&LIST_ITEM_CONTAINS_BLOCK != 0 || flags&LIST_ITEM_BEGINNING_OF_LIST != 0 {
+		doubleSpace(out)
+	}
+	out.WriteString("<li>")
+	out.Write(text)
+	out.WriteString("</li>\n")
+}
+
+func (options *Html) Paragraph(out *bytes.Buffer, text func() bool) {
+	marker := out.Len()
+	doubleSpace(out)
+
+	out.WriteString("<p>")
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	out.WriteString("</p>\n")
+}
+
+func (options *Html) AutoLink(out *bytes.Buffer, link []byte, kind int) {
+	skipRanges := htmlEntity.FindAllIndex(link, -1)
+	if options.flags&HTML_SAFELINK != 0 && !isSafeLink(link) && kind != LINK_TYPE_EMAIL {
+		// mark it but don't link it if it is not a safe link: no smartypants
+		out.WriteString("<tt>")
+		entityEscapeWithSkip(out, link, skipRanges)
+		out.WriteString("</tt>")
+		return
+	}
+
+	out.WriteString("<a href=\"")
+	if kind == LINK_TYPE_EMAIL {
+		out.WriteString("mailto:")
+	} else {
+		options.maybeWriteAbsolutePrefix(out, link)
+	}
+
+	entityEscapeWithSkip(out, link, skipRanges)
+
+	var relAttrs []string
+	if options.flags&HTML_NOFOLLOW_LINKS != 0 && !isRelativeLink(link) {
+		relAttrs = append(relAttrs, "nofollow")
+	}
+	if options.flags&HTML_NOREFERRER_LINKS != 0 && !isRelativeLink(link) {
+		relAttrs = append(relAttrs, "noreferrer")
+	}
+	if len(relAttrs) > 0 {
+		out.WriteString(fmt.Sprintf("\" rel=\"%s", strings.Join(relAttrs, " ")))
+	}
+
+	// blank target only add to external link
+	if options.flags&HTML_HREF_TARGET_BLANK != 0 && !isRelativeLink(link) {
+		out.WriteString("\" target=\"_blank")
+	}
+
+	out.WriteString("\">")
+
+	// Pretty print: if we get an email address as
+	// an actual URI, e.g. `mailto:foo@bar.com`, we don't
+	// want to print the `mailto:` prefix
+	switch {
+	case bytes.HasPrefix(link, []byte("mailto://")):
+		attrEscape(out, link[len("mailto://"):])
+	case bytes.HasPrefix(link, []byte("mailto:")):
+		attrEscape(out, link[len("mailto:"):])
+	default:
+		entityEscapeWithSkip(out, link, skipRanges)
+	}
+
+	out.WriteString("</a>")
+}
+
+func (options *Html) CodeSpan(out *bytes.Buffer, text []byte) {
+	out.WriteString("<code>")
+	attrEscape(out, text)
+	out.WriteString("</code>")
+}
+
+func (options *Html) DoubleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("<strong>")
+	out.Write(text)
+	out.WriteString("</strong>")
+}
+
+func (options *Html) Emphasis(out *bytes.Buffer, text []byte) {
+	if len(text) == 0 {
+		return
+	}
+	out.WriteString("<em>")
+	out.Write(text)
+	out.WriteString("</em>")
+}
+
+func (options *Html) maybeWriteAbsolutePrefix(out *bytes.Buffer, link []byte) {
+	if options.parameters.AbsolutePrefix != "" && isRelativeLink(link) && link[0] != '.' {
+		out.WriteString(options.parameters.AbsolutePrefix)
+		if link[0] != '/' {
+			out.WriteByte('/')
+		}
+	}
+}
+
+func (options *Html) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
+	if options.flags&HTML_SKIP_IMAGES != 0 {
+		return
+	}
+
+	out.WriteString("<img src=\"")
+	options.maybeWriteAbsolutePrefix(out, link)
+	attrEscape(out, link)
+	out.WriteString("\" alt=\"")
+	if len(alt) > 0 {
+		attrEscape(out, alt)
+	}
+	if len(title) > 0 {
+		out.WriteString("\" title=\"")
+		attrEscape(out, title)
+	}
+
+	out.WriteByte('"')
+	out.WriteString(options.closeTag)
+	return
+}
+
+func (options *Html) LineBreak(out *bytes.Buffer) {
+	out.WriteString("<br")
+	out.WriteString(options.closeTag)
+}
+
+func (options *Html) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
+	if options.flags&HTML_SKIP_LINKS != 0 {
+		// write the link text out but don't link it, just mark it with typewriter font
+		out.WriteString("<tt>")
+		attrEscape(out, content)
+		out.WriteString("</tt>")
+		return
+	}
+
+	if options.flags&HTML_SAFELINK != 0 && !isSafeLink(link) {
+		// write the link text out but don't link it, just mark it with typewriter font
+		out.WriteString("<tt>")
+		attrEscape(out, content)
+		out.WriteString("</tt>")
+		return
+	}
+
+	out.WriteString("<a href=\"")
+	options.maybeWriteAbsolutePrefix(out, link)
+	attrEscape(out, link)
+	if len(title) > 0 {
+		out.WriteString("\" title=\"")
+		attrEscape(out, title)
+	}
+	var relAttrs []string
+	if options.flags&HTML_NOFOLLOW_LINKS != 0 && !isRelativeLink(link) {
+		relAttrs = append(relAttrs, "nofollow")
+	}
+	if options.flags&HTML_NOREFERRER_LINKS != 0 && !isRelativeLink(link) {
+		relAttrs = append(relAttrs, "noreferrer")
+	}
+	if len(relAttrs) > 0 {
+		out.WriteString(fmt.Sprintf("\" rel=\"%s", strings.Join(relAttrs, " ")))
+	}
+
+	// blank target only add to external link
+	if options.flags&HTML_HREF_TARGET_BLANK != 0 && !isRelativeLink(link) {
+		out.WriteString("\" target=\"_blank")
+	}
+
+	out.WriteString("\">")
+	out.Write(content)
+	out.WriteString("</a>")
+	return
+}
+
+func (options *Html) RawHtmlTag(out *bytes.Buffer, text []byte) {
+	if options.flags&HTML_SKIP_HTML != 0 {
+		return
+	}
+	if options.flags&HTML_SKIP_STYLE != 0 && isHtmlTag(text, "style") {
+		return
+	}
+	if options.flags&HTML_SKIP_LINKS != 0 && isHtmlTag(text, "a") {
+		return
+	}
+	if options.flags&HTML_SKIP_IMAGES != 0 && isHtmlTag(text, "img") {
+		return
+	}
+	out.Write(text)
+}
+
+func (options *Html) TripleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("<strong><em>")
+	out.Write(text)
+	out.WriteString("</em></strong>")
+}
+
+func (options *Html) StrikeThrough(out *bytes.Buffer, text []byte) {
+	out.WriteString("<del>")
+	out.Write(text)
+	out.WriteString("</del>")
+}
+
+func (options *Html) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
+	slug := slugify(ref)
+	out.WriteString(`<sup class="footnote-ref" id="`)
+	out.WriteString(`fnref:`)
+	out.WriteString(options.parameters.FootnoteAnchorPrefix)
+	out.Write(slug)
+	out.WriteString(`"><a rel="footnote" href="#`)
+	out.WriteString(`fn:`)
+	out.WriteString(options.parameters.FootnoteAnchorPrefix)
+	out.Write(slug)
+	out.WriteString(`">`)
+	out.WriteString(strconv.Itoa(id))
+	out.WriteString(`</a></sup>`)
+}
+
+func (options *Html) Entity(out *bytes.Buffer, entity []byte) {
+	out.Write(entity)
+}
+
+func (options *Html) NormalText(out *bytes.Buffer, text []byte) {
+	if options.flags&HTML_USE_SMARTYPANTS != 0 {
+		options.Smartypants(out, text)
+	} else {
+		attrEscape(out, text)
+	}
+}
+
+func (options *Html) Smartypants(out *bytes.Buffer, text []byte) {
+	smrt := smartypantsData{false, false}
+
+	// first do normal entity escaping
+	var escaped bytes.Buffer
+	attrEscape(&escaped, text)
+	text = escaped.Bytes()
+
+	mark := 0
+	for i := 0; i < len(text); i++ {
+		if action := options.smartypants[text[i]]; action != nil {
+			if i > mark {
+				out.Write(text[mark:i])
+			}
+
+			previousChar := byte(0)
+			if i > 0 {
+				previousChar = text[i-1]
+			}
+			i += action(out, &smrt, previousChar, text[i:])
+			mark = i + 1
+		}
+	}
+
+	if mark < len(text) {
+		out.Write(text[mark:])
+	}
+}
+
+func (options *Html) DocumentHeader(out *bytes.Buffer) {
+	if options.flags&HTML_COMPLETE_PAGE == 0 {
+		return
+	}
+
+	ending := ""
+	if options.flags&HTML_USE_XHTML != 0 {
+		out.WriteString("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" ")
+		out.WriteString("\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n")
+		out.WriteString("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n")
+		ending = " /"
+	} else {
+		out.WriteString("<!DOCTYPE html>\n")
+		out.WriteString("<html>\n")
+	}
+	out.WriteString("<head>\n")
+	out.WriteString("  <title>")
+	options.NormalText(out, []byte(options.title))
+	out.WriteString("</title>\n")
+	out.WriteString("  <meta name=\"GENERATOR\" content=\"Blackfriday Markdown Processor v")
+	out.WriteString(VERSION)
+	out.WriteString("\"")
+	out.WriteString(ending)
+	out.WriteString(">\n")
+	out.WriteString("  <meta charset=\"utf-8\"")
+	out.WriteString(ending)
+	out.WriteString(">\n")
+	if options.css != "" {
+		out.WriteString("  <link rel=\"stylesheet\" type=\"text/css\" href=\"")
+		attrEscape(out, []byte(options.css))
+		out.WriteString("\"")
+		out.WriteString(ending)
+		out.WriteString(">\n")
+	}
+	out.WriteString("</head>\n")
+	out.WriteString("<body>\n")
+
+	options.tocMarker = out.Len()
+}
+
+func (options *Html) DocumentFooter(out *bytes.Buffer) {
+	// finalize and insert the table of contents
+	if options.flags&HTML_TOC != 0 {
+		options.TocFinalize()
+
+		// now we have to insert the table of contents into the document
+		var temp bytes.Buffer
+
+		// start by making a copy of everything after the document header
+		temp.Write(out.Bytes()[options.tocMarker:])
+
+		// now clear the copied material from the main output buffer
+		out.Truncate(options.tocMarker)
+
+		// corner case spacing issue
+		if options.flags&HTML_COMPLETE_PAGE != 0 {
+			out.WriteByte('\n')
+		}
+
+		// insert the table of contents
+		out.WriteString("<nav>\n")
+		out.Write(options.toc.Bytes())
+		out.WriteString("</nav>\n")
+
+		// corner case spacing issue
+		if options.flags&HTML_COMPLETE_PAGE == 0 && options.flags&HTML_OMIT_CONTENTS == 0 {
+			out.WriteByte('\n')
+		}
+
+		// write out everything that came after it
+		if options.flags&HTML_OMIT_CONTENTS == 0 {
+			out.Write(temp.Bytes())
+		}
+	}
+
+	if options.flags&HTML_COMPLETE_PAGE != 0 {
+		out.WriteString("\n</body>\n")
+		out.WriteString("</html>\n")
+	}
+
+}
+
+func (options *Html) TocHeaderWithAnchor(text []byte, level int, anchor string) {
+	for level > options.currentLevel {
+		switch {
+		case bytes.HasSuffix(options.toc.Bytes(), []byte("</li>\n")):
+			// this sublist can nest underneath a header
+			size := options.toc.Len()
+			options.toc.Truncate(size - len("</li>\n"))
+
+		case options.currentLevel > 0:
+			options.toc.WriteString("<li>")
+		}
+		if options.toc.Len() > 0 {
+			options.toc.WriteByte('\n')
+		}
+		options.toc.WriteString("<ul>\n")
+		options.currentLevel++
+	}
+
+	for level < options.currentLevel {
+		options.toc.WriteString("</ul>")
+		if options.currentLevel > 1 {
+			options.toc.WriteString("</li>\n")
+		}
+		options.currentLevel--
+	}
+
+	options.toc.WriteString("<li><a href=\"#")
+	if anchor != "" {
+		options.toc.WriteString(anchor)
+	} else {
+		options.toc.WriteString("toc_")
+		options.toc.WriteString(strconv.Itoa(options.headerCount))
+	}
+	options.toc.WriteString("\">")
+	options.headerCount++
+
+	options.toc.Write(text)
+
+	options.toc.WriteString("</a></li>\n")
+}
+
+func (options *Html) TocHeader(text []byte, level int) {
+	options.TocHeaderWithAnchor(text, level, "")
+}
+
+func (options *Html) TocFinalize() {
+	for options.currentLevel > 1 {
+		options.toc.WriteString("</ul></li>\n")
+		options.currentLevel--
+	}
+
+	if options.currentLevel > 0 {
+		options.toc.WriteString("</ul>\n")
+	}
+}
+
+func isHtmlTag(tag []byte, tagname string) bool {
+	found, _ := findHtmlTagPos(tag, tagname)
+	return found
+}
+
+// Look for a character, but ignore it when it's in any kind of quotes, it
+// might be JavaScript
+func skipUntilCharIgnoreQuotes(html []byte, start int, char byte) int {
+	inSingleQuote := false
+	inDoubleQuote := false
+	inGraveQuote := false
+	i := start
+	for i < len(html) {
+		switch {
+		case html[i] == char && !inSingleQuote && !inDoubleQuote && !inGraveQuote:
+			return i
+		case html[i] == '\'':
+			inSingleQuote = !inSingleQuote
+		case html[i] == '"':
+			inDoubleQuote = !inDoubleQuote
+		case html[i] == '`':
+			inGraveQuote = !inGraveQuote
+		}
+		i++
+	}
+	return start
+}
+
+func findHtmlTagPos(tag []byte, tagname string) (bool, int) {
+	i := 0
+	if i < len(tag) && tag[0] != '<' {
+		return false, -1
+	}
+	i++
+	i = skipSpace(tag, i)
+
+	if i < len(tag) && tag[i] == '/' {
+		i++
+	}
+
+	i = skipSpace(tag, i)
+	j := 0
+	for ; i < len(tag); i, j = i+1, j+1 {
+		if j >= len(tagname) {
+			break
+		}
+
+		if strings.ToLower(string(tag[i]))[0] != tagname[j] {
+			return false, -1
+		}
+	}
+
+	if i == len(tag) {
+		return false, -1
+	}
+
+	rightAngle := skipUntilCharIgnoreQuotes(tag, i, '>')
+	if rightAngle > i {
+		return true, rightAngle
+	}
+
+	return false, -1
+}
+
+func skipUntilChar(text []byte, start int, char byte) int {
+	i := start
+	for i < len(text) && text[i] != char {
+		i++
+	}
+	return i
+}
+
+func skipSpace(tag []byte, i int) int {
+	for i < len(tag) && isspace(tag[i]) {
+		i++
+	}
+	return i
+}
+
+func doubleSpace(out *bytes.Buffer) {
+	if out.Len() > 0 {
+		out.WriteByte('\n')
+	}
+}
+
+func isRelativeLink(link []byte) (yes bool) {
+	// a tag begin with '#'
+	if link[0] == '#' {
+		return true
+	}
+
+	// link begin with '/' but not '//', the second maybe a protocol relative link
+	if len(link) >= 2 && link[0] == '/' && link[1] != '/' {
+		return true
+	}
+
+	// only the root '/'
+	if len(link) == 1 && link[0] == '/' {
+		return true
+	}
+
+	// current directory : begin with "./"
+	if bytes.HasPrefix(link, []byte("./")) {
+		return true
+	}
+
+	// parent directory : begin with "../"
+	if bytes.HasPrefix(link, []byte("../")) {
+		return true
+	}
+
+	return false
+}
+
+func (options *Html) ensureUniqueHeaderID(id string) string {
+	for count, found := options.headerIDs[id]; found; count, found = options.headerIDs[id] {
+		tmp := fmt.Sprintf("%s-%d", id, count+1)
+
+		if _, tmpFound := options.headerIDs[tmp]; !tmpFound {
+			options.headerIDs[id] = count + 1
+			id = tmp
+		} else {
+			id = id + "-1"
+		}
+	}
+
+	if _, found := options.headerIDs[id]; !found {
+		options.headerIDs[id] = 0
+	}
+
+	return id
+}
diff --git a/vendor/src/github.com/russross/blackfriday/inline.go b/vendor/src/github.com/russross/blackfriday/inline.go
new file mode 100644
index 0000000..b3ec847
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/inline.go
@@ -0,0 +1,1096 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Functions to parse inline elements.
+//
+
+package blackfriday
+
+import (
+	"bytes"
+	"regexp"
+	"strconv"
+)
+
+var (
+	urlRe    = `((https?|ftp):\/\/|\/)[-A-Za-z0-9+&@#\/%?=~_|!:,.;\(\)]+`
+	anchorRe = regexp.MustCompile(`^(<a\shref="` + urlRe + `"(\stitle="[^"<>]+")?\s?>` + urlRe + `<\/a>)`)
+)
+
+// Functions to parse text within a block
+// Each function returns the number of chars taken care of
+// data is the complete block being rendered
+// offset is the number of valid chars before the current cursor
+
+func (p *parser) inline(out *bytes.Buffer, data []byte) {
+	// this is called recursively: enforce a maximum depth
+	if p.nesting >= p.maxNesting {
+		return
+	}
+	p.nesting++
+
+	i, end := 0, 0
+	for i < len(data) {
+		// copy inactive chars into the output
+		for end < len(data) && p.inlineCallback[data[end]] == nil {
+			end++
+		}
+
+		p.r.NormalText(out, data[i:end])
+
+		if end >= len(data) {
+			break
+		}
+		i = end
+
+		// call the trigger
+		handler := p.inlineCallback[data[end]]
+		if consumed := handler(p, out, data, i); consumed == 0 {
+			// no action from the callback; buffer the byte for later
+			end = i + 1
+		} else {
+			// skip past whatever the callback used
+			i += consumed
+			end = i
+		}
+	}
+
+	p.nesting--
+}
+
+// single and double emphasis parsing
+func emphasis(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	data = data[offset:]
+	c := data[0]
+	ret := 0
+
+	if len(data) > 2 && data[1] != c {
+		// whitespace cannot follow an opening emphasis;
+		// strikethrough only takes two characters '~~'
+		if c == '~' || isspace(data[1]) {
+			return 0
+		}
+		if ret = helperEmphasis(p, out, data[1:], c); ret == 0 {
+			return 0
+		}
+
+		return ret + 1
+	}
+
+	if len(data) > 3 && data[1] == c && data[2] != c {
+		if isspace(data[2]) {
+			return 0
+		}
+		if ret = helperDoubleEmphasis(p, out, data[2:], c); ret == 0 {
+			return 0
+		}
+
+		return ret + 2
+	}
+
+	if len(data) > 4 && data[1] == c && data[2] == c && data[3] != c {
+		if c == '~' || isspace(data[3]) {
+			return 0
+		}
+		if ret = helperTripleEmphasis(p, out, data, 3, c); ret == 0 {
+			return 0
+		}
+
+		return ret + 3
+	}
+
+	return 0
+}
+
+func codeSpan(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	data = data[offset:]
+
+	nb := 0
+
+	// count the number of backticks in the delimiter
+	for nb < len(data) && data[nb] == '`' {
+		nb++
+	}
+
+	// find the next delimiter
+	i, end := 0, 0
+	for end = nb; end < len(data) && i < nb; end++ {
+		if data[end] == '`' {
+			i++
+		} else {
+			i = 0
+		}
+	}
+
+	// no matching delimiter?
+	if i < nb && end >= len(data) {
+		return 0
+	}
+
+	// trim outside whitespace
+	fBegin := nb
+	for fBegin < end && data[fBegin] == ' ' {
+		fBegin++
+	}
+
+	fEnd := end - nb
+	for fEnd > fBegin && data[fEnd-1] == ' ' {
+		fEnd--
+	}
+
+	// render the code span
+	if fBegin != fEnd {
+		p.r.CodeSpan(out, data[fBegin:fEnd])
+	}
+
+	return end
+
+}
+
+// newline preceded by two spaces becomes <br>
+// newline without two spaces works when EXTENSION_HARD_LINE_BREAK is enabled
+func lineBreak(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	// remove trailing spaces from out
+	outBytes := out.Bytes()
+	end := len(outBytes)
+	eol := end
+	for eol > 0 && outBytes[eol-1] == ' ' {
+		eol--
+	}
+	out.Truncate(eol)
+
+	precededByTwoSpaces := offset >= 2 && data[offset-2] == ' ' && data[offset-1] == ' '
+	precededByBackslash := offset >= 1 && data[offset-1] == '\\' // see http://spec.commonmark.org/0.18/#example-527
+	precededByBackslash = precededByBackslash && p.flags&EXTENSION_BACKSLASH_LINE_BREAK != 0
+
+	// should there be a hard line break here?
+	if p.flags&EXTENSION_HARD_LINE_BREAK == 0 && !precededByTwoSpaces && !precededByBackslash {
+		return 0
+	}
+
+	if precededByBackslash && eol > 0 {
+		out.Truncate(eol - 1)
+	}
+	p.r.LineBreak(out)
+	return 1
+}
+
+type linkType int
+
+const (
+	linkNormal linkType = iota
+	linkImg
+	linkDeferredFootnote
+	linkInlineFootnote
+)
+
+// '[': parse a link or an image or a footnote
+func link(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	// no links allowed inside regular links, footnote, and deferred footnotes
+	if p.insideLink && (offset > 0 && data[offset-1] == '[' || len(data)-1 > offset && data[offset+1] == '^') {
+		return 0
+	}
+
+	// [text] == regular link
+	// ![alt] == image
+	// ^[text] == inline footnote
+	// [^refId] == deferred footnote
+	var t linkType
+	if offset > 0 && data[offset-1] == '!' {
+		t = linkImg
+	} else if p.flags&EXTENSION_FOOTNOTES != 0 {
+		if offset > 0 && data[offset-1] == '^' {
+			t = linkInlineFootnote
+		} else if len(data)-1 > offset && data[offset+1] == '^' {
+			t = linkDeferredFootnote
+		}
+	}
+
+	data = data[offset:]
+
+	var (
+		i           = 1
+		noteId      int
+		title, link []byte
+		textHasNl   = false
+	)
+
+	if t == linkDeferredFootnote {
+		i++
+	}
+
+	// look for the matching closing bracket
+	for level := 1; level > 0 && i < len(data); i++ {
+		switch {
+		case data[i] == '\n':
+			textHasNl = true
+
+		case data[i-1] == '\\':
+			continue
+
+		case data[i] == '[':
+			level++
+
+		case data[i] == ']':
+			level--
+			if level <= 0 {
+				i-- // compensate for extra i++ in for loop
+			}
+		}
+	}
+
+	if i >= len(data) {
+		return 0
+	}
+
+	txtE := i
+	i++
+
+	// skip any amount of whitespace or newline
+	// (this is much more lax than original markdown syntax)
+	for i < len(data) && isspace(data[i]) {
+		i++
+	}
+
+	// inline style link
+	switch {
+	case i < len(data) && data[i] == '(':
+		// skip initial whitespace
+		i++
+
+		for i < len(data) && isspace(data[i]) {
+			i++
+		}
+
+		linkB := i
+
+		// look for link end: ' " )
+	findlinkend:
+		for i < len(data) {
+			switch {
+			case data[i] == '\\':
+				i += 2
+
+			case data[i] == ')' || data[i] == '\'' || data[i] == '"':
+				break findlinkend
+
+			default:
+				i++
+			}
+		}
+
+		if i >= len(data) {
+			return 0
+		}
+		linkE := i
+
+		// look for title end if present
+		titleB, titleE := 0, 0
+		if data[i] == '\'' || data[i] == '"' {
+			i++
+			titleB = i
+
+		findtitleend:
+			for i < len(data) {
+				switch {
+				case data[i] == '\\':
+					i += 2
+
+				case data[i] == ')':
+					break findtitleend
+
+				default:
+					i++
+				}
+			}
+
+			if i >= len(data) {
+				return 0
+			}
+
+			// skip whitespace after title
+			titleE = i - 1
+			for titleE > titleB && isspace(data[titleE]) {
+				titleE--
+			}
+
+			// check for closing quote presence
+			if data[titleE] != '\'' && data[titleE] != '"' {
+				titleB, titleE = 0, 0
+				linkE = i
+			}
+		}
+
+		// remove whitespace at the end of the link
+		for linkE > linkB && isspace(data[linkE-1]) {
+			linkE--
+		}
+
+		// remove optional angle brackets around the link
+		if data[linkB] == '<' {
+			linkB++
+		}
+		if data[linkE-1] == '>' {
+			linkE--
+		}
+
+		// build escaped link and title
+		if linkE > linkB {
+			link = data[linkB:linkE]
+		}
+
+		if titleE > titleB {
+			title = data[titleB:titleE]
+		}
+
+		i++
+
+	// reference style link
+	case i < len(data)-1 && data[i] == '[' && data[i+1] != '^':
+		var id []byte
+
+		// look for the id
+		i++
+		linkB := i
+		for i < len(data) && data[i] != ']' {
+			i++
+		}
+		if i >= len(data) {
+			return 0
+		}
+		linkE := i
+
+		// find the reference
+		if linkB == linkE {
+			if textHasNl {
+				var b bytes.Buffer
+
+				for j := 1; j < txtE; j++ {
+					switch {
+					case data[j] != '\n':
+						b.WriteByte(data[j])
+					case data[j-1] != ' ':
+						b.WriteByte(' ')
+					}
+				}
+
+				id = b.Bytes()
+			} else {
+				id = data[1:txtE]
+			}
+		} else {
+			id = data[linkB:linkE]
+		}
+
+		// find the reference with matching id (ids are case-insensitive)
+		key := string(bytes.ToLower(id))
+		lr, ok := p.refs[key]
+		if !ok {
+			return 0
+
+		}
+
+		// keep link and title from reference
+		link = lr.link
+		title = lr.title
+		i++
+
+	// shortcut reference style link or reference or inline footnote
+	default:
+		var id []byte
+
+		// craft the id
+		if textHasNl {
+			var b bytes.Buffer
+
+			for j := 1; j < txtE; j++ {
+				switch {
+				case data[j] != '\n':
+					b.WriteByte(data[j])
+				case data[j-1] != ' ':
+					b.WriteByte(' ')
+				}
+			}
+
+			id = b.Bytes()
+		} else {
+			if t == linkDeferredFootnote {
+				id = data[2:txtE] // get rid of the ^
+			} else {
+				id = data[1:txtE]
+			}
+		}
+
+		key := string(bytes.ToLower(id))
+		if t == linkInlineFootnote {
+			// create a new reference
+			noteId = len(p.notes) + 1
+
+			var fragment []byte
+			if len(id) > 0 {
+				if len(id) < 16 {
+					fragment = make([]byte, len(id))
+				} else {
+					fragment = make([]byte, 16)
+				}
+				copy(fragment, slugify(id))
+			} else {
+				fragment = append([]byte("footnote-"), []byte(strconv.Itoa(noteId))...)
+			}
+
+			ref := &reference{
+				noteId:   noteId,
+				hasBlock: false,
+				link:     fragment,
+				title:    id,
+			}
+
+			p.notes = append(p.notes, ref)
+
+			link = ref.link
+			title = ref.title
+		} else {
+			// find the reference with matching id
+			lr, ok := p.refs[key]
+			if !ok {
+				return 0
+			}
+
+			if t == linkDeferredFootnote {
+				lr.noteId = len(p.notes) + 1
+				p.notes = append(p.notes, lr)
+			}
+
+			// keep link and title from reference
+			link = lr.link
+			// if inline footnote, title == footnote contents
+			title = lr.title
+			noteId = lr.noteId
+		}
+
+		// rewind the whitespace
+		i = txtE + 1
+	}
+
+	// build content: img alt is escaped, link content is parsed
+	var content bytes.Buffer
+	if txtE > 1 {
+		if t == linkImg {
+			content.Write(data[1:txtE])
+		} else {
+			// links cannot contain other links, so turn off link parsing temporarily
+			insideLink := p.insideLink
+			p.insideLink = true
+			p.inline(&content, data[1:txtE])
+			p.insideLink = insideLink
+		}
+	}
+
+	var uLink []byte
+	if t == linkNormal || t == linkImg {
+		if len(link) > 0 {
+			var uLinkBuf bytes.Buffer
+			unescapeText(&uLinkBuf, link)
+			uLink = uLinkBuf.Bytes()
+		}
+
+		// links need something to click on and somewhere to go
+		if len(uLink) == 0 || (t == linkNormal && content.Len() == 0) {
+			return 0
+		}
+	}
+
+	// call the relevant rendering function
+	switch t {
+	case linkNormal:
+		p.r.Link(out, uLink, title, content.Bytes())
+
+	case linkImg:
+		outSize := out.Len()
+		outBytes := out.Bytes()
+		if outSize > 0 && outBytes[outSize-1] == '!' {
+			out.Truncate(outSize - 1)
+		}
+
+		p.r.Image(out, uLink, title, content.Bytes())
+
+	case linkInlineFootnote:
+		outSize := out.Len()
+		outBytes := out.Bytes()
+		if outSize > 0 && outBytes[outSize-1] == '^' {
+			out.Truncate(outSize - 1)
+		}
+
+		p.r.FootnoteRef(out, link, noteId)
+
+	case linkDeferredFootnote:
+		p.r.FootnoteRef(out, link, noteId)
+
+	default:
+		return 0
+	}
+
+	return i
+}
+
+// '<' when tags or autolinks are allowed
+func leftAngle(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	data = data[offset:]
+	altype := LINK_TYPE_NOT_AUTOLINK
+	end := tagLength(data, &altype)
+
+	if end > 2 {
+		if altype != LINK_TYPE_NOT_AUTOLINK {
+			var uLink bytes.Buffer
+			unescapeText(&uLink, data[1:end+1-2])
+			if uLink.Len() > 0 {
+				p.r.AutoLink(out, uLink.Bytes(), altype)
+			}
+		} else {
+			p.r.RawHtmlTag(out, data[:end])
+		}
+	}
+
+	return end
+}
+
+// '\\' backslash escape
+var escapeChars = []byte("\\`*_{}[]()#+-.!:|&<>~")
+
+func escape(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	data = data[offset:]
+
+	if len(data) > 1 {
+		if bytes.IndexByte(escapeChars, data[1]) < 0 {
+			return 0
+		}
+
+		p.r.NormalText(out, data[1:2])
+	}
+
+	return 2
+}
+
+func unescapeText(ob *bytes.Buffer, src []byte) {
+	i := 0
+	for i < len(src) {
+		org := i
+		for i < len(src) && src[i] != '\\' {
+			i++
+		}
+
+		if i > org {
+			ob.Write(src[org:i])
+		}
+
+		if i+1 >= len(src) {
+			break
+		}
+
+		ob.WriteByte(src[i+1])
+		i += 2
+	}
+}
+
+// '&' escaped when it doesn't belong to an entity
+// valid entities are assumed to be anything matching &#?[A-Za-z0-9]+;
+func entity(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	data = data[offset:]
+
+	end := 1
+
+	if end < len(data) && data[end] == '#' {
+		end++
+	}
+
+	for end < len(data) && isalnum(data[end]) {
+		end++
+	}
+
+	if end < len(data) && data[end] == ';' {
+		end++ // real entity
+	} else {
+		return 0 // lone '&'
+	}
+
+	p.r.Entity(out, data[:end])
+
+	return end
+}
+
+func linkEndsWithEntity(data []byte, linkEnd int) bool {
+	entityRanges := htmlEntity.FindAllIndex(data[:linkEnd], -1)
+	if entityRanges != nil && entityRanges[len(entityRanges)-1][1] == linkEnd {
+		return true
+	}
+	return false
+}
+
+func autoLink(p *parser, out *bytes.Buffer, data []byte, offset int) int {
+	// quick check to rule out most false hits on ':'
+	if p.insideLink || len(data) < offset+3 || data[offset+1] != '/' || data[offset+2] != '/' {
+		return 0
+	}
+
+	// Now a more expensive check to see if we're not inside an anchor element
+	anchorStart := offset
+	offsetFromAnchor := 0
+	for anchorStart > 0 && data[anchorStart] != '<' {
+		anchorStart--
+		offsetFromAnchor++
+	}
+
+	anchorStr := anchorRe.Find(data[anchorStart:])
+	if anchorStr != nil {
+		out.Write(anchorStr[offsetFromAnchor:])
+		return len(anchorStr) - offsetFromAnchor
+	}
+
+	// scan backward for a word boundary
+	rewind := 0
+	for offset-rewind > 0 && rewind <= 7 && isletter(data[offset-rewind-1]) {
+		rewind++
+	}
+	if rewind > 6 { // longest supported protocol is "mailto" which has 6 letters
+		return 0
+	}
+
+	origData := data
+	data = data[offset-rewind:]
+
+	if !isSafeLink(data) {
+		return 0
+	}
+
+	linkEnd := 0
+	for linkEnd < len(data) && !isEndOfLink(data[linkEnd]) {
+		linkEnd++
+	}
+
+	// Skip punctuation at the end of the link
+	if (data[linkEnd-1] == '.' || data[linkEnd-1] == ',') && data[linkEnd-2] != '\\' {
+		linkEnd--
+	}
+
+	// But don't skip semicolon if it's a part of escaped entity:
+	if data[linkEnd-1] == ';' && data[linkEnd-2] != '\\' && !linkEndsWithEntity(data, linkEnd) {
+		linkEnd--
+	}
+
+	// See if the link finishes with a punctuation sign that can be closed.
+	var copen byte
+	switch data[linkEnd-1] {
+	case '"':
+		copen = '"'
+	case '\'':
+		copen = '\''
+	case ')':
+		copen = '('
+	case ']':
+		copen = '['
+	case '}':
+		copen = '{'
+	default:
+		copen = 0
+	}
+
+	if copen != 0 {
+		bufEnd := offset - rewind + linkEnd - 2
+
+		openDelim := 1
+
+		/* Try to close the final punctuation sign in this same line;
+		 * if we managed to close it outside of the URL, that means that it's
+		 * not part of the URL. If it closes inside the URL, that means it
+		 * is part of the URL.
+		 *
+		 * Examples:
+		 *
+		 *      foo http://www.pokemon.com/Pikachu_(Electric) bar
+		 *              => http://www.pokemon.com/Pikachu_(Electric)
+		 *
+		 *      foo (http://www.pokemon.com/Pikachu_(Electric)) bar
+		 *              => http://www.pokemon.com/Pikachu_(Electric)
+		 *
+		 *      foo http://www.pokemon.com/Pikachu_(Electric)) bar
+		 *              => http://www.pokemon.com/Pikachu_(Electric))
+		 *
+		 *      (foo http://www.pokemon.com/Pikachu_(Electric)) bar
+		 *              => foo http://www.pokemon.com/Pikachu_(Electric)
+		 */
+
+		for bufEnd >= 0 && origData[bufEnd] != '\n' && openDelim != 0 {
+			if origData[bufEnd] == data[linkEnd-1] {
+				openDelim++
+			}
+
+			if origData[bufEnd] == copen {
+				openDelim--
+			}
+
+			bufEnd--
+		}
+
+		if openDelim == 0 {
+			linkEnd--
+		}
+	}
+
+	// we were triggered on the ':', so we need to rewind the output a bit
+	if out.Len() >= rewind {
+		out.Truncate(len(out.Bytes()) - rewind)
+	}
+
+	var uLink bytes.Buffer
+	unescapeText(&uLink, data[:linkEnd])
+
+	if uLink.Len() > 0 {
+		p.r.AutoLink(out, uLink.Bytes(), LINK_TYPE_NORMAL)
+	}
+
+	return linkEnd - rewind
+}
+
+func isEndOfLink(char byte) bool {
+	return isspace(char) || char == '<'
+}
+
+var validUris = [][]byte{[]byte("http://"), []byte("https://"), []byte("ftp://"), []byte("mailto://")}
+var validPaths = [][]byte{[]byte("/"), []byte("./"), []byte("../")}
+
+func isSafeLink(link []byte) bool {
+	for _, path := range validPaths {
+		if len(link) >= len(path) && bytes.Equal(link[:len(path)], path) {
+			if len(link) == len(path) {
+				return true
+			} else if isalnum(link[len(path)]) {
+				return true
+			}
+		}
+	}
+
+	for _, prefix := range validUris {
+		// TODO: handle unicode here
+		// case-insensitive prefix test
+		if len(link) > len(prefix) && bytes.Equal(bytes.ToLower(link[:len(prefix)]), prefix) && isalnum(link[len(prefix)]) {
+			return true
+		}
+	}
+
+	return false
+}
+
+// return the length of the given tag, or 0 is it's not valid
+func tagLength(data []byte, autolink *int) int {
+	var i, j int
+
+	// a valid tag can't be shorter than 3 chars
+	if len(data) < 3 {
+		return 0
+	}
+
+	// begins with a '<' optionally followed by '/', followed by letter or number
+	if data[0] != '<' {
+		return 0
+	}
+	if data[1] == '/' {
+		i = 2
+	} else {
+		i = 1
+	}
+
+	if !isalnum(data[i]) {
+		return 0
+	}
+
+	// scheme test
+	*autolink = LINK_TYPE_NOT_AUTOLINK
+
+	// try to find the beginning of an URI
+	for i < len(data) && (isalnum(data[i]) || data[i] == '.' || data[i] == '+' || data[i] == '-') {
+		i++
+	}
+
+	if i > 1 && i < len(data) && data[i] == '@' {
+		if j = isMailtoAutoLink(data[i:]); j != 0 {
+			*autolink = LINK_TYPE_EMAIL
+			return i + j
+		}
+	}
+
+	if i > 2 && i < len(data) && data[i] == ':' {
+		*autolink = LINK_TYPE_NORMAL
+		i++
+	}
+
+	// complete autolink test: no whitespace or ' or "
+	switch {
+	case i >= len(data):
+		*autolink = LINK_TYPE_NOT_AUTOLINK
+	case *autolink != 0:
+		j = i
+
+		for i < len(data) {
+			if data[i] == '\\' {
+				i += 2
+			} else if data[i] == '>' || data[i] == '\'' || data[i] == '"' || isspace(data[i]) {
+				break
+			} else {
+				i++
+			}
+
+		}
+
+		if i >= len(data) {
+			return 0
+		}
+		if i > j && data[i] == '>' {
+			return i + 1
+		}
+
+		// one of the forbidden chars has been found
+		*autolink = LINK_TYPE_NOT_AUTOLINK
+	}
+
+	// look for something looking like a tag end
+	for i < len(data) && data[i] != '>' {
+		i++
+	}
+	if i >= len(data) {
+		return 0
+	}
+	return i + 1
+}
+
+// look for the address part of a mail autolink and '>'
+// this is less strict than the original markdown e-mail address matching
+func isMailtoAutoLink(data []byte) int {
+	nb := 0
+
+	// address is assumed to be: [-@._a-zA-Z0-9]+ with exactly one '@'
+	for i := 0; i < len(data); i++ {
+		if isalnum(data[i]) {
+			continue
+		}
+
+		switch data[i] {
+		case '@':
+			nb++
+
+		case '-', '.', '_':
+			break
+
+		case '>':
+			if nb == 1 {
+				return i + 1
+			} else {
+				return 0
+			}
+		default:
+			return 0
+		}
+	}
+
+	return 0
+}
+
+// look for the next emph char, skipping other constructs
+func helperFindEmphChar(data []byte, c byte) int {
+	i := 1
+
+	for i < len(data) {
+		for i < len(data) && data[i] != c && data[i] != '`' && data[i] != '[' {
+			i++
+		}
+		if i >= len(data) {
+			return 0
+		}
+		if data[i] == c {
+			return i
+		}
+
+		// do not count escaped chars
+		if i != 0 && data[i-1] == '\\' {
+			i++
+			continue
+		}
+
+		if data[i] == '`' {
+			// skip a code span
+			tmpI := 0
+			i++
+			for i < len(data) && data[i] != '`' {
+				if tmpI == 0 && data[i] == c {
+					tmpI = i
+				}
+				i++
+			}
+			if i >= len(data) {
+				return tmpI
+			}
+			i++
+		} else if data[i] == '[' {
+			// skip a link
+			tmpI := 0
+			i++
+			for i < len(data) && data[i] != ']' {
+				if tmpI == 0 && data[i] == c {
+					tmpI = i
+				}
+				i++
+			}
+			i++
+			for i < len(data) && (data[i] == ' ' || data[i] == '\n') {
+				i++
+			}
+			if i >= len(data) {
+				return tmpI
+			}
+			if data[i] != '[' && data[i] != '(' { // not a link
+				if tmpI > 0 {
+					return tmpI
+				} else {
+					continue
+				}
+			}
+			cc := data[i]
+			i++
+			for i < len(data) && data[i] != cc {
+				if tmpI == 0 && data[i] == c {
+					return i
+				}
+				i++
+			}
+			if i >= len(data) {
+				return tmpI
+			}
+			i++
+		}
+	}
+	return 0
+}
+
+func helperEmphasis(p *parser, out *bytes.Buffer, data []byte, c byte) int {
+	i := 0
+
+	// skip one symbol if coming from emph3
+	if len(data) > 1 && data[0] == c && data[1] == c {
+		i = 1
+	}
+
+	for i < len(data) {
+		length := helperFindEmphChar(data[i:], c)
+		if length == 0 {
+			return 0
+		}
+		i += length
+		if i >= len(data) {
+			return 0
+		}
+
+		if i+1 < len(data) && data[i+1] == c {
+			i++
+			continue
+		}
+
+		if data[i] == c && !isspace(data[i-1]) {
+
+			if p.flags&EXTENSION_NO_INTRA_EMPHASIS != 0 {
+				if !(i+1 == len(data) || isspace(data[i+1]) || ispunct(data[i+1])) {
+					continue
+				}
+			}
+
+			var work bytes.Buffer
+			p.inline(&work, data[:i])
+			p.r.Emphasis(out, work.Bytes())
+			return i + 1
+		}
+	}
+
+	return 0
+}
+
+func helperDoubleEmphasis(p *parser, out *bytes.Buffer, data []byte, c byte) int {
+	i := 0
+
+	for i < len(data) {
+		length := helperFindEmphChar(data[i:], c)
+		if length == 0 {
+			return 0
+		}
+		i += length
+
+		if i+1 < len(data) && data[i] == c && data[i+1] == c && i > 0 && !isspace(data[i-1]) {
+			var work bytes.Buffer
+			p.inline(&work, data[:i])
+
+			if work.Len() > 0 {
+				// pick the right renderer
+				if c == '~' {
+					p.r.StrikeThrough(out, work.Bytes())
+				} else {
+					p.r.DoubleEmphasis(out, work.Bytes())
+				}
+			}
+			return i + 2
+		}
+		i++
+	}
+	return 0
+}
+
+func helperTripleEmphasis(p *parser, out *bytes.Buffer, data []byte, offset int, c byte) int {
+	i := 0
+	origData := data
+	data = data[offset:]
+
+	for i < len(data) {
+		length := helperFindEmphChar(data[i:], c)
+		if length == 0 {
+			return 0
+		}
+		i += length
+
+		// skip whitespace preceded symbols
+		if data[i] != c || isspace(data[i-1]) {
+			continue
+		}
+
+		switch {
+		case i+2 < len(data) && data[i+1] == c && data[i+2] == c:
+			// triple symbol found
+			var work bytes.Buffer
+
+			p.inline(&work, data[:i])
+			if work.Len() > 0 {
+				p.r.TripleEmphasis(out, work.Bytes())
+			}
+			return i + 3
+		case (i+1 < len(data) && data[i+1] == c):
+			// double symbol found, hand over to emph1
+			length = helperEmphasis(p, out, origData[offset-2:], c)
+			if length == 0 {
+				return 0
+			} else {
+				return length - 2
+			}
+		default:
+			// single symbol found, hand over to emph2
+			length = helperDoubleEmphasis(p, out, origData[offset-1:], c)
+			if length == 0 {
+				return 0
+			} else {
+				return length - 1
+			}
+		}
+	}
+	return 0
+}
diff --git a/vendor/src/github.com/russross/blackfriday/inline_test.go b/vendor/src/github.com/russross/blackfriday/inline_test.go
new file mode 100644
index 0000000..4e67d5c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/inline_test.go
@@ -0,0 +1,958 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Unit tests for inline parsing
+//
+
+package blackfriday
+
+import (
+	"regexp"
+	"testing"
+
+	"strings"
+)
+
+func runMarkdownInline(input string, extensions, htmlFlags int, params HtmlRendererParameters) string {
+	extensions |= EXTENSION_AUTOLINK
+	extensions |= EXTENSION_STRIKETHROUGH
+
+	htmlFlags |= HTML_USE_XHTML
+
+	renderer := HtmlRendererWithParameters(htmlFlags, "", "", params)
+
+	return string(Markdown([]byte(input), renderer, extensions))
+}
+
+func doTestsInline(t *testing.T, tests []string) {
+	doTestsInlineParam(t, tests, 0, 0, HtmlRendererParameters{})
+}
+
+func doLinkTestsInline(t *testing.T, tests []string) {
+	doTestsInline(t, tests)
+
+	prefix := "http://localhost"
+	params := HtmlRendererParameters{AbsolutePrefix: prefix}
+	transformTests := transformLinks(tests, prefix)
+	doTestsInlineParam(t, transformTests, 0, 0, params)
+	doTestsInlineParam(t, transformTests, 0, commonHtmlFlags, params)
+}
+
+func doSafeTestsInline(t *testing.T, tests []string) {
+	doTestsInlineParam(t, tests, 0, HTML_SAFELINK, HtmlRendererParameters{})
+
+	// All the links in this test should not have the prefix appended, so
+	// just rerun it with different parameters and the same expectations.
+	prefix := "http://localhost"
+	params := HtmlRendererParameters{AbsolutePrefix: prefix}
+	transformTests := transformLinks(tests, prefix)
+	doTestsInlineParam(t, transformTests, 0, HTML_SAFELINK, params)
+}
+
+func doTestsInlineParam(t *testing.T, tests []string, extensions, htmlFlags int,
+	params HtmlRendererParameters) {
+	// catch and report panics
+	var candidate string
+	/*
+		defer func() {
+			if err := recover(); err != nil {
+				t.Errorf("\npanic while processing [%#v] (%v)\n", candidate, err)
+			}
+		}()
+	*/
+
+	for i := 0; i+1 < len(tests); i += 2 {
+		input := tests[i]
+		candidate = input
+		expected := tests[i+1]
+
+		actual := runMarkdownInline(candidate, extensions, htmlFlags, params)
+		if actual != expected {
+			t.Errorf("\nInput   [%#v]\nExpected[%#v]\nActual  [%#v]",
+				candidate, expected, actual)
+		}
+
+		// now test every substring to stress test bounds checking
+		if !testing.Short() {
+			for start := 0; start < len(input); start++ {
+				for end := start + 1; end <= len(input); end++ {
+					candidate = input[start:end]
+					_ = runMarkdownInline(candidate, extensions, htmlFlags, params)
+				}
+			}
+		}
+	}
+}
+
+func transformLinks(tests []string, prefix string) []string {
+	newTests := make([]string, len(tests))
+	anchorRe := regexp.MustCompile(`<a href="/(.*?)"`)
+	imgRe := regexp.MustCompile(`<img src="/(.*?)"`)
+	for i, test := range tests {
+		if i%2 == 1 {
+			test = anchorRe.ReplaceAllString(test, `<a href="`+prefix+`/$1"`)
+			test = imgRe.ReplaceAllString(test, `<img src="`+prefix+`/$1"`)
+		}
+		newTests[i] = test
+	}
+	return newTests
+}
+
+func TestEmphasis(t *testing.T) {
+	var tests = []string{
+		"nothing inline\n",
+		"<p>nothing inline</p>\n",
+
+		"simple *inline* test\n",
+		"<p>simple <em>inline</em> test</p>\n",
+
+		"*at the* beginning\n",
+		"<p><em>at the</em> beginning</p>\n",
+
+		"at the *end*\n",
+		"<p>at the <em>end</em></p>\n",
+
+		"*try two* in *one line*\n",
+		"<p><em>try two</em> in <em>one line</em></p>\n",
+
+		"over *two\nlines* test\n",
+		"<p>over <em>two\nlines</em> test</p>\n",
+
+		"odd *number of* markers* here\n",
+		"<p>odd <em>number of</em> markers* here</p>\n",
+
+		"odd *number\nof* markers* here\n",
+		"<p>odd <em>number\nof</em> markers* here</p>\n",
+
+		"simple _inline_ test\n",
+		"<p>simple <em>inline</em> test</p>\n",
+
+		"_at the_ beginning\n",
+		"<p><em>at the</em> beginning</p>\n",
+
+		"at the _end_\n",
+		"<p>at the <em>end</em></p>\n",
+
+		"_try two_ in _one line_\n",
+		"<p><em>try two</em> in <em>one line</em></p>\n",
+
+		"over _two\nlines_ test\n",
+		"<p>over <em>two\nlines</em> test</p>\n",
+
+		"odd _number of_ markers_ here\n",
+		"<p>odd <em>number of</em> markers_ here</p>\n",
+
+		"odd _number\nof_ markers_ here\n",
+		"<p>odd <em>number\nof</em> markers_ here</p>\n",
+
+		"mix of *markers_\n",
+		"<p>mix of *markers_</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestStrong(t *testing.T) {
+	var tests = []string{
+		"nothing inline\n",
+		"<p>nothing inline</p>\n",
+
+		"simple **inline** test\n",
+		"<p>simple <strong>inline</strong> test</p>\n",
+
+		"**at the** beginning\n",
+		"<p><strong>at the</strong> beginning</p>\n",
+
+		"at the **end**\n",
+		"<p>at the <strong>end</strong></p>\n",
+
+		"**try two** in **one line**\n",
+		"<p><strong>try two</strong> in <strong>one line</strong></p>\n",
+
+		"over **two\nlines** test\n",
+		"<p>over <strong>two\nlines</strong> test</p>\n",
+
+		"odd **number of** markers** here\n",
+		"<p>odd <strong>number of</strong> markers** here</p>\n",
+
+		"odd **number\nof** markers** here\n",
+		"<p>odd <strong>number\nof</strong> markers** here</p>\n",
+
+		"simple __inline__ test\n",
+		"<p>simple <strong>inline</strong> test</p>\n",
+
+		"__at the__ beginning\n",
+		"<p><strong>at the</strong> beginning</p>\n",
+
+		"at the __end__\n",
+		"<p>at the <strong>end</strong></p>\n",
+
+		"__try two__ in __one line__\n",
+		"<p><strong>try two</strong> in <strong>one line</strong></p>\n",
+
+		"over __two\nlines__ test\n",
+		"<p>over <strong>two\nlines</strong> test</p>\n",
+
+		"odd __number of__ markers__ here\n",
+		"<p>odd <strong>number of</strong> markers__ here</p>\n",
+
+		"odd __number\nof__ markers__ here\n",
+		"<p>odd <strong>number\nof</strong> markers__ here</p>\n",
+
+		"mix of **markers__\n",
+		"<p>mix of **markers__</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestEmphasisMix(t *testing.T) {
+	var tests = []string{
+		"***triple emphasis***\n",
+		"<p><strong><em>triple emphasis</em></strong></p>\n",
+
+		"***triple\nemphasis***\n",
+		"<p><strong><em>triple\nemphasis</em></strong></p>\n",
+
+		"___triple emphasis___\n",
+		"<p><strong><em>triple emphasis</em></strong></p>\n",
+
+		"***triple emphasis___\n",
+		"<p>***triple emphasis___</p>\n",
+
+		"*__triple emphasis__*\n",
+		"<p><em><strong>triple emphasis</strong></em></p>\n",
+
+		"__*triple emphasis*__\n",
+		"<p><strong><em>triple emphasis</em></strong></p>\n",
+
+		"**improper *nesting** is* bad\n",
+		"<p><strong>improper *nesting</strong> is* bad</p>\n",
+
+		"*improper **nesting* is** bad\n",
+		"<p><em>improper **nesting</em> is** bad</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestEmphasisLink(t *testing.T) {
+	var tests = []string{
+		"[first](before) *text[second] (inside)text* [third](after)\n",
+		"<p><a href=\"before\">first</a> <em>text<a href=\"inside\">second</a>text</em> <a href=\"after\">third</a></p>\n",
+
+		"*incomplete [link] definition*\n",
+		"<p><em>incomplete [link] definition</em></p>\n",
+
+		"*it's [emphasis*] (not link)\n",
+		"<p><em>it's [emphasis</em>] (not link)</p>\n",
+
+		"*it's [emphasis*] and *[asterisk]\n",
+		"<p><em>it's [emphasis</em>] and *[asterisk]</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestStrikeThrough(t *testing.T) {
+	var tests = []string{
+		"nothing inline\n",
+		"<p>nothing inline</p>\n",
+
+		"simple ~~inline~~ test\n",
+		"<p>simple <del>inline</del> test</p>\n",
+
+		"~~at the~~ beginning\n",
+		"<p><del>at the</del> beginning</p>\n",
+
+		"at the ~~end~~\n",
+		"<p>at the <del>end</del></p>\n",
+
+		"~~try two~~ in ~~one line~~\n",
+		"<p><del>try two</del> in <del>one line</del></p>\n",
+
+		"over ~~two\nlines~~ test\n",
+		"<p>over <del>two\nlines</del> test</p>\n",
+
+		"odd ~~number of~~ markers~~ here\n",
+		"<p>odd <del>number of</del> markers~~ here</p>\n",
+
+		"odd ~~number\nof~~ markers~~ here\n",
+		"<p>odd <del>number\nof</del> markers~~ here</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestCodeSpan(t *testing.T) {
+	var tests = []string{
+		"`source code`\n",
+		"<p><code>source code</code></p>\n",
+
+		"` source code with spaces `\n",
+		"<p><code>source code with spaces</code></p>\n",
+
+		"` source code with spaces `not here\n",
+		"<p><code>source code with spaces</code>not here</p>\n",
+
+		"a `single marker\n",
+		"<p>a `single marker</p>\n",
+
+		"a single multi-tick marker with ``` no text\n",
+		"<p>a single multi-tick marker with ``` no text</p>\n",
+
+		"markers with ` ` a space\n",
+		"<p>markers with  a space</p>\n",
+
+		"`source code` and a `stray\n",
+		"<p><code>source code</code> and a `stray</p>\n",
+
+		"`source *with* _awkward characters_ in it`\n",
+		"<p><code>source *with* _awkward characters_ in it</code></p>\n",
+
+		"`split over\ntwo lines`\n",
+		"<p><code>split over\ntwo lines</code></p>\n",
+
+		"```multiple ticks``` for the marker\n",
+		"<p><code>multiple ticks</code> for the marker</p>\n",
+
+		"```multiple ticks `with` ticks inside```\n",
+		"<p><code>multiple ticks `with` ticks inside</code></p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestLineBreak(t *testing.T) {
+	var tests = []string{
+		"this line  \nhas a break\n",
+		"<p>this line<br />\nhas a break</p>\n",
+
+		"this line \ndoes not\n",
+		"<p>this line\ndoes not</p>\n",
+
+		"this line\\\ndoes not\n",
+		"<p>this line\\\ndoes not</p>\n",
+
+		"this line\\ \ndoes not\n",
+		"<p>this line\\\ndoes not</p>\n",
+
+		"this has an   \nextra space\n",
+		"<p>this has an<br />\nextra space</p>\n",
+	}
+	doTestsInline(t, tests)
+
+	tests = []string{
+		"this line  \nhas a break\n",
+		"<p>this line<br />\nhas a break</p>\n",
+
+		"this line \ndoes not\n",
+		"<p>this line\ndoes not</p>\n",
+
+		"this line\\\nhas a break\n",
+		"<p>this line<br />\nhas a break</p>\n",
+
+		"this line\\ \ndoes not\n",
+		"<p>this line\\\ndoes not</p>\n",
+
+		"this has an   \nextra space\n",
+		"<p>this has an<br />\nextra space</p>\n",
+	}
+	doTestsInlineParam(t, tests, EXTENSION_BACKSLASH_LINE_BREAK, 0, HtmlRendererParameters{})
+}
+
+func TestInlineLink(t *testing.T) {
+	var tests = []string{
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+
+		"[foo with a title](/bar/ \"title\")\n",
+		"<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n",
+
+		"[foo with a title](/bar/\t\"title\")\n",
+		"<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n",
+
+		"[foo with a title](/bar/ \"title\"  )\n",
+		"<p><a href=\"/bar/\" title=\"title\">foo with a title</a></p>\n",
+
+		"[foo with a title](/bar/ title with no quotes)\n",
+		"<p><a href=\"/bar/ title with no quotes\">foo with a title</a></p>\n",
+
+		"[foo]()\n",
+		"<p>[foo]()</p>\n",
+
+		"![foo](/bar/)\n",
+		"<p><img src=\"/bar/\" alt=\"foo\" />\n</p>\n",
+
+		"![foo with a title](/bar/ \"title\")\n",
+		"<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" />\n</p>\n",
+
+		"![foo with a title](/bar/\t\"title\")\n",
+		"<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" />\n</p>\n",
+
+		"![foo with a title](/bar/ \"title\"  )\n",
+		"<p><img src=\"/bar/\" alt=\"foo with a title\" title=\"title\" />\n</p>\n",
+
+		"![foo with a title](/bar/ title with no quotes)\n",
+		"<p><img src=\"/bar/ title with no quotes\" alt=\"foo with a title\" />\n</p>\n",
+
+		"![](img.jpg)\n",
+		"<p><img src=\"img.jpg\" alt=\"\" />\n</p>\n",
+
+		"[link](url)\n",
+		"<p><a href=\"url\">link</a></p>\n",
+
+		"![foo]()\n",
+		"<p>![foo]()</p>\n",
+
+		"[a link]\t(/with_a_tab/)\n",
+		"<p><a href=\"/with_a_tab/\">a link</a></p>\n",
+
+		"[a link]  (/with_spaces/)\n",
+		"<p><a href=\"/with_spaces/\">a link</a></p>\n",
+
+		"[text (with) [[nested] (brackets)]](/url/)\n",
+		"<p><a href=\"/url/\">text (with) [[nested] (brackets)]</a></p>\n",
+
+		"[text (with) [broken nested] (brackets)]](/url/)\n",
+		"<p>[text (with) <a href=\"brackets\">broken nested</a>]](/url/)</p>\n",
+
+		"[text\nwith a newline](/link/)\n",
+		"<p><a href=\"/link/\">text\nwith a newline</a></p>\n",
+
+		"[text in brackets] [followed](/by a link/)\n",
+		"<p>[text in brackets] <a href=\"/by a link/\">followed</a></p>\n",
+
+		"[link with\\] a closing bracket](/url/)\n",
+		"<p><a href=\"/url/\">link with] a closing bracket</a></p>\n",
+
+		"[link with\\[ an opening bracket](/url/)\n",
+		"<p><a href=\"/url/\">link with[ an opening bracket</a></p>\n",
+
+		"[link with\\) a closing paren](/url/)\n",
+		"<p><a href=\"/url/\">link with) a closing paren</a></p>\n",
+
+		"[link with\\( an opening paren](/url/)\n",
+		"<p><a href=\"/url/\">link with( an opening paren</a></p>\n",
+
+		"[link](  with whitespace)\n",
+		"<p><a href=\"with whitespace\">link</a></p>\n",
+
+		"[link](  with whitespace   )\n",
+		"<p><a href=\"with whitespace\">link</a></p>\n",
+
+		"[![image](someimage)](with image)\n",
+		"<p><a href=\"with image\"><img src=\"someimage\" alt=\"image\" />\n</a></p>\n",
+
+		"[link](url \"one quote)\n",
+		"<p><a href=\"url &quot;one quote\">link</a></p>\n",
+
+		"[link](url 'one quote)\n",
+		"<p><a href=\"url 'one quote\">link</a></p>\n",
+
+		"[link](<url>)\n",
+		"<p><a href=\"url\">link</a></p>\n",
+
+		"[link & ampersand](/url/)\n",
+		"<p><a href=\"/url/\">link &amp; ampersand</a></p>\n",
+
+		"[link &amp; ampersand](/url/)\n",
+		"<p><a href=\"/url/\">link &amp; ampersand</a></p>\n",
+
+		"[link](/url/&query)\n",
+		"<p><a href=\"/url/&amp;query\">link</a></p>\n",
+
+		"[[t]](/t)\n",
+		"<p><a href=\"/t\">[t]</a></p>\n",
+
+		"[link](</>)\n",
+		"<p><a href=\"/\">link</a></p>\n",
+
+		"[link](<./>)\n",
+		"<p><a href=\"./\">link</a></p>\n",
+
+		"[link](<../>)\n",
+		"<p><a href=\"../\">link</a></p>\n",
+	}
+	doLinkTestsInline(t, tests)
+
+}
+
+func TestRelAttrLink(t *testing.T) {
+	var nofollowTests = []string{
+		"[foo](http://bar.com/foo/)\n",
+		"<p><a href=\"http://bar.com/foo/\" rel=\"nofollow\">foo</a></p>\n",
+
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+
+		"[foo](/)\n",
+		"<p><a href=\"/\">foo</a></p>\n",
+
+		"[foo](./)\n",
+		"<p><a href=\"./\">foo</a></p>\n",
+
+		"[foo](../)\n",
+		"<p><a href=\"../\">foo</a></p>\n",
+
+		"[foo](../bar)\n",
+		"<p><a href=\"../bar\">foo</a></p>\n",
+	}
+	doTestsInlineParam(t, nofollowTests, 0, HTML_SAFELINK|HTML_NOFOLLOW_LINKS,
+		HtmlRendererParameters{})
+
+	var noreferrerTests = []string{
+		"[foo](http://bar.com/foo/)\n",
+		"<p><a href=\"http://bar.com/foo/\" rel=\"noreferrer\">foo</a></p>\n",
+
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+	}
+	doTestsInlineParam(t, noreferrerTests, 0, HTML_SAFELINK|HTML_NOREFERRER_LINKS,
+		HtmlRendererParameters{})
+
+	var nofollownoreferrerTests = []string{
+		"[foo](http://bar.com/foo/)\n",
+		"<p><a href=\"http://bar.com/foo/\" rel=\"nofollow noreferrer\">foo</a></p>\n",
+
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+	}
+	doTestsInlineParam(t, nofollownoreferrerTests, 0, HTML_SAFELINK|HTML_NOFOLLOW_LINKS|HTML_NOREFERRER_LINKS,
+		HtmlRendererParameters{})
+}
+
+func TestHrefTargetBlank(t *testing.T) {
+	var tests = []string{
+		// internal link
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+
+		"[foo](/)\n",
+		"<p><a href=\"/\">foo</a></p>\n",
+
+		"[foo](./)\n",
+		"<p><a href=\"./\">foo</a></p>\n",
+
+		"[foo](./bar)\n",
+		"<p><a href=\"./bar\">foo</a></p>\n",
+
+		"[foo](../)\n",
+		"<p><a href=\"../\">foo</a></p>\n",
+
+		"[foo](../bar)\n",
+		"<p><a href=\"../bar\">foo</a></p>\n",
+
+		"[foo](http://example.com)\n",
+		"<p><a href=\"http://example.com\" target=\"_blank\">foo</a></p>\n",
+	}
+	doTestsInlineParam(t, tests, 0, HTML_SAFELINK|HTML_HREF_TARGET_BLANK, HtmlRendererParameters{})
+}
+
+func TestSafeInlineLink(t *testing.T) {
+	var tests = []string{
+		"[foo](/bar/)\n",
+		"<p><a href=\"/bar/\">foo</a></p>\n",
+
+		"[foo](/)\n",
+		"<p><a href=\"/\">foo</a></p>\n",
+
+		"[foo](./)\n",
+		"<p><a href=\"./\">foo</a></p>\n",
+
+		"[foo](../)\n",
+		"<p><a href=\"../\">foo</a></p>\n",
+
+		"[foo](http://bar/)\n",
+		"<p><a href=\"http://bar/\">foo</a></p>\n",
+
+		"[foo](https://bar/)\n",
+		"<p><a href=\"https://bar/\">foo</a></p>\n",
+
+		"[foo](ftp://bar/)\n",
+		"<p><a href=\"ftp://bar/\">foo</a></p>\n",
+
+		"[foo](mailto://bar/)\n",
+		"<p><a href=\"mailto://bar/\">foo</a></p>\n",
+
+		// Not considered safe
+		"[foo](baz://bar/)\n",
+		"<p><tt>foo</tt></p>\n",
+	}
+	doSafeTestsInline(t, tests)
+}
+
+func TestReferenceLink(t *testing.T) {
+	var tests = []string{
+		"[link][ref]\n",
+		"<p>[link][ref]</p>\n",
+
+		"[link][ref]\n   [ref]: /url/ \"title\"\n",
+		"<p><a href=\"/url/\" title=\"title\">link</a></p>\n",
+
+		"[link][ref]\n   [ref]: /url/\n",
+		"<p><a href=\"/url/\">link</a></p>\n",
+
+		"   [ref]: /url/\n",
+		"",
+
+		"   [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n",
+		"",
+
+		"   [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n    [4spaces]: /url/\n",
+		"<pre><code>[4spaces]: /url/\n</code></pre>\n",
+
+		"[hmm](ref2)\n   [ref]: /url/\n[ref2]: /url/\n [ref3]: /url/\n",
+		"<p><a href=\"ref2\">hmm</a></p>\n",
+
+		"[ref]\n",
+		"<p>[ref]</p>\n",
+
+		"[ref]\n   [ref]: /url/ \"title\"\n",
+		"<p><a href=\"/url/\" title=\"title\">ref</a></p>\n",
+
+		"[ref]\n   [ref]: ../url/ \"title\"\n",
+		"<p><a href=\"../url/\" title=\"title\">ref</a></p>\n",
+	}
+	doLinkTestsInline(t, tests)
+}
+
+func TestTags(t *testing.T) {
+	var tests = []string{
+		"a <span>tag</span>\n",
+		"<p>a <span>tag</span></p>\n",
+
+		"<span>tag</span>\n",
+		"<p><span>tag</span></p>\n",
+
+		"<span>mismatch</spandex>\n",
+		"<p><span>mismatch</spandex></p>\n",
+
+		"a <singleton /> tag\n",
+		"<p>a <singleton /> tag</p>\n",
+	}
+	doTestsInline(t, tests)
+}
+
+func TestAutoLink(t *testing.T) {
+	var tests = []string{
+		"http://foo.com/\n",
+		"<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"1 http://foo.com/\n",
+		"<p>1 <a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"1http://foo.com/\n",
+		"<p>1<a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"1.http://foo.com/\n",
+		"<p>1.<a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"1. http://foo.com/\n",
+		"<ol>\n<li><a href=\"http://foo.com/\">http://foo.com/</a></li>\n</ol>\n",
+
+		"-http://foo.com/\n",
+		"<p>-<a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"- http://foo.com/\n",
+		"<ul>\n<li><a href=\"http://foo.com/\">http://foo.com/</a></li>\n</ul>\n",
+
+		"_http://foo.com/\n",
+		"<p>_<a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"令狐http://foo.com/\n",
+		"<p>令狐<a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"令狐 http://foo.com/\n",
+		"<p>令狐 <a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"ahttp://foo.com/\n",
+		"<p>ahttp://foo.com/</p>\n",
+
+		">http://foo.com/\n",
+		"<blockquote>\n<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n</blockquote>\n",
+
+		"> http://foo.com/\n",
+		"<blockquote>\n<p><a href=\"http://foo.com/\">http://foo.com/</a></p>\n</blockquote>\n",
+
+		"go to <http://foo.com/>\n",
+		"<p>go to <a href=\"http://foo.com/\">http://foo.com/</a></p>\n",
+
+		"a secure <https://link.org>\n",
+		"<p>a secure <a href=\"https://link.org\">https://link.org</a></p>\n",
+
+		"an email <mailto:some@one.com>\n",
+		"<p>an email <a href=\"mailto:some@one.com\">some@one.com</a></p>\n",
+
+		"an email <mailto://some@one.com>\n",
+		"<p>an email <a href=\"mailto://some@one.com\">some@one.com</a></p>\n",
+
+		"an email <some@one.com>\n",
+		"<p>an email <a href=\"mailto:some@one.com\">some@one.com</a></p>\n",
+
+		"an ftp <ftp://old.com>\n",
+		"<p>an ftp <a href=\"ftp://old.com\">ftp://old.com</a></p>\n",
+
+		"an ftp <ftp:old.com>\n",
+		"<p>an ftp <a href=\"ftp:old.com\">ftp:old.com</a></p>\n",
+
+		"a link with <http://new.com?query=foo&bar>\n",
+		"<p>a link with <a href=\"http://new.com?query=foo&amp;bar\">" +
+			"http://new.com?query=foo&amp;bar</a></p>\n",
+
+		"quotes mean a tag <http://new.com?query=\"foo\"&bar>\n",
+		"<p>quotes mean a tag <http://new.com?query=\"foo\"&bar></p>\n",
+
+		"quotes mean a tag <http://new.com?query='foo'&bar>\n",
+		"<p>quotes mean a tag <http://new.com?query='foo'&bar></p>\n",
+
+		"unless escaped <http://new.com?query=\\\"foo\\\"&bar>\n",
+		"<p>unless escaped <a href=\"http://new.com?query=&quot;foo&quot;&amp;bar\">" +
+			"http://new.com?query=&quot;foo&quot;&amp;bar</a></p>\n",
+
+		"even a > can be escaped <http://new.com?q=\\>&etc>\n",
+		"<p>even a &gt; can be escaped <a href=\"http://new.com?q=&gt;&amp;etc\">" +
+			"http://new.com?q=&gt;&amp;etc</a></p>\n",
+
+		"<a href=\"http://fancy.com\">http://fancy.com</a>\n",
+		"<p><a href=\"http://fancy.com\">http://fancy.com</a></p>\n",
+
+		"<a href=\"http://fancy.com\">This is a link</a>\n",
+		"<p><a href=\"http://fancy.com\">This is a link</a></p>\n",
+
+		"<a href=\"http://www.fancy.com/A_B.pdf\">http://www.fancy.com/A_B.pdf</a>\n",
+		"<p><a href=\"http://www.fancy.com/A_B.pdf\">http://www.fancy.com/A_B.pdf</a></p>\n",
+
+		"(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (\n",
+		"<p>(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (</p>\n",
+
+		"(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (part two: <a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a>)).\n",
+		"<p>(<a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a> (part two: <a href=\"http://www.fancy.com/A_B\">http://www.fancy.com/A_B</a>)).</p>\n",
+
+		"http://www.foo.com<br />\n",
+		"<p><a href=\"http://www.foo.com\">http://www.foo.com</a><br /></p>\n",
+
+		"http://foo.com/viewtopic.php?f=18&amp;t=297",
+		"<p><a href=\"http://foo.com/viewtopic.php?f=18&amp;t=297\">http://foo.com/viewtopic.php?f=18&amp;t=297</a></p>\n",
+
+		"http://foo.com/viewtopic.php?param=&quot;18&quot;zz",
+		"<p><a href=\"http://foo.com/viewtopic.php?param=&quot;18&quot;zz\">http://foo.com/viewtopic.php?param=&quot;18&quot;zz</a></p>\n",
+
+		"http://foo.com/viewtopic.php?param=&quot;18&quot;",
+		"<p><a href=\"http://foo.com/viewtopic.php?param=&quot;18&quot;\">http://foo.com/viewtopic.php?param=&quot;18&quot;</a></p>\n",
+	}
+	doLinkTestsInline(t, tests)
+}
+
+var footnoteTests = []string{
+	"testing footnotes.[^a]\n\n[^a]: This is the note\n",
+	`<p>testing footnotes.<sup class="footnote-ref" id="fnref:a"><a rel="footnote" href="#fn:a">1</a></sup></p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:a">This is the note
+</li>
+</ol>
+</div>
+`,
+
+	`testing long[^b] notes.
+
+[^b]: Paragraph 1
+
+	Paragraph 2
+
+	` + "```\n\tsome code\n\t```" + `
+
+	Paragraph 3
+
+No longer in the footnote
+`,
+	`<p>testing long<sup class="footnote-ref" id="fnref:b"><a rel="footnote" href="#fn:b">1</a></sup> notes.</p>
+
+<p>No longer in the footnote</p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:b"><p>Paragraph 1</p>
+
+<p>Paragraph 2</p>
+
+<p><code>
+some code
+</code></p>
+
+<p>Paragraph 3</p>
+</li>
+</ol>
+</div>
+`,
+
+	`testing[^c] multiple[^d] notes.
+
+[^c]: this is [note] c
+
+
+omg
+
+[^d]: this is note d
+
+what happens here
+
+[note]: /link/c
+
+`,
+	`<p>testing<sup class="footnote-ref" id="fnref:c"><a rel="footnote" href="#fn:c">1</a></sup> multiple<sup class="footnote-ref" id="fnref:d"><a rel="footnote" href="#fn:d">2</a></sup> notes.</p>
+
+<p>omg</p>
+
+<p>what happens here</p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:c">this is <a href="/link/c">note</a> c
+</li>
+<li id="fn:d">this is note d
+</li>
+</ol>
+</div>
+`,
+
+	"testing inline^[this is the note] notes.\n",
+	`<p>testing inline<sup class="footnote-ref" id="fnref:this-is-the-note"><a rel="footnote" href="#fn:this-is-the-note">1</a></sup> notes.</p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:this-is-the-note">this is the note</li>
+</ol>
+</div>
+`,
+
+	"testing multiple[^1] types^[inline note] of notes[^2]\n\n[^2]: the second deferred note\n[^1]: the first deferred note\n\n\twhich happens to be a block\n",
+	`<p>testing multiple<sup class="footnote-ref" id="fnref:1"><a rel="footnote" href="#fn:1">1</a></sup> types<sup class="footnote-ref" id="fnref:inline-note"><a rel="footnote" href="#fn:inline-note">2</a></sup> of notes<sup class="footnote-ref" id="fnref:2"><a rel="footnote" href="#fn:2">3</a></sup></p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:1"><p>the first deferred note</p>
+
+<p>which happens to be a block</p>
+</li>
+<li id="fn:inline-note">inline note</li>
+<li id="fn:2">the second deferred note
+</li>
+</ol>
+</div>
+`,
+
+	`This is a footnote[^1]^[and this is an inline footnote]
+
+[^1]: the footnote text.
+
+    may be multiple paragraphs.
+`,
+	`<p>This is a footnote<sup class="footnote-ref" id="fnref:1"><a rel="footnote" href="#fn:1">1</a></sup><sup class="footnote-ref" id="fnref:and-this-is-an-i"><a rel="footnote" href="#fn:and-this-is-an-i">2</a></sup></p>
+<div class="footnotes">
+
+<hr />
+
+<ol>
+<li id="fn:1"><p>the footnote text.</p>
+
+<p>may be multiple paragraphs.</p>
+</li>
+<li id="fn:and-this-is-an-i">and this is an inline footnote</li>
+</ol>
+</div>
+`,
+
+	"empty footnote[^]\n\n[^]: fn text",
+	"<p>empty footnote<sup class=\"footnote-ref\" id=\"fnref:\"><a rel=\"footnote\" href=\"#fn:\">1</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:\">fn text\n</li>\n</ol>\n</div>\n",
+
+	"Some text.[^note1]\n\n[^note1]: fn1",
+	"<p>Some text.<sup class=\"footnote-ref\" id=\"fnref:note1\"><a rel=\"footnote\" href=\"#fn:note1\">1</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:note1\">fn1\n</li>\n</ol>\n</div>\n",
+
+	"Some text.[^note1][^note2]\n\n[^note1]: fn1\n[^note2]: fn2\n",
+	"<p>Some text.<sup class=\"footnote-ref\" id=\"fnref:note1\"><a rel=\"footnote\" href=\"#fn:note1\">1</a></sup><sup class=\"footnote-ref\" id=\"fnref:note2\"><a rel=\"footnote\" href=\"#fn:note2\">2</a></sup></p>\n<div class=\"footnotes\">\n\n<hr />\n\n<ol>\n<li id=\"fn:note1\">fn1\n</li>\n<li id=\"fn:note2\">fn2\n</li>\n</ol>\n</div>\n",
+}
+
+func TestFootnotes(t *testing.T) {
+	doTestsInlineParam(t, footnoteTests, EXTENSION_FOOTNOTES, 0, HtmlRendererParameters{})
+}
+
+func TestFootnotesWithParameters(t *testing.T) {
+	tests := make([]string, len(footnoteTests))
+
+	prefix := "testPrefix"
+	returnText := "ret"
+	re := regexp.MustCompile(`(?ms)<li id="fn:(\S+?)">(.*?)</li>`)
+
+	// Transform the test expectations to match the parameters we're using.
+	for i, test := range footnoteTests {
+		if i%2 == 1 {
+			test = strings.Replace(test, "fn:", "fn:"+prefix, -1)
+			test = strings.Replace(test, "fnref:", "fnref:"+prefix, -1)
+			test = re.ReplaceAllString(test, `<li id="fn:$1">$2 <a class="footnote-return" href="#fnref:$1">ret</a></li>`)
+		}
+		tests[i] = test
+	}
+
+	params := HtmlRendererParameters{
+		FootnoteAnchorPrefix:       prefix,
+		FootnoteReturnLinkContents: returnText,
+	}
+
+	doTestsInlineParam(t, tests, EXTENSION_FOOTNOTES, HTML_FOOTNOTE_RETURN_LINKS, params)
+}
+
+func TestSmartDoubleQuotes(t *testing.T) {
+	var tests = []string{
+		"this should be normal \"quoted\" text.\n",
+		"<p>this should be normal &ldquo;quoted&rdquo; text.</p>\n",
+		"this \" single double\n",
+		"<p>this &ldquo; single double</p>\n",
+		"two pair of \"some\" quoted \"text\".\n",
+		"<p>two pair of &ldquo;some&rdquo; quoted &ldquo;text&rdquo;.</p>\n"}
+
+	doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{})
+}
+
+func TestSmartAngledDoubleQuotes(t *testing.T) {
+	var tests = []string{
+		"this should be angled \"quoted\" text.\n",
+		"<p>this should be angled &laquo;quoted&raquo; text.</p>\n",
+		"this \" single double\n",
+		"<p>this &laquo; single double</p>\n",
+		"two pair of \"some\" quoted \"text\".\n",
+		"<p>two pair of &laquo;some&raquo; quoted &laquo;text&raquo;.</p>\n"}
+
+	doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_ANGLED_QUOTES, HtmlRendererParameters{})
+}
+
+func TestSmartFractions(t *testing.T) {
+	var tests = []string{
+		"1/2, 1/4 and 3/4; 1/4th and 3/4ths\n",
+		"<p>&frac12;, &frac14; and &frac34;; &frac14;th and &frac34;ths</p>\n",
+		"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
+		"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}
+
+	doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS, HtmlRendererParameters{})
+
+	tests = []string{
+		"1/2, 2/3, 81/100 and 1000000/1048576.\n",
+		"<p><sup>1</sup>&frasl;<sub>2</sub>, <sup>2</sup>&frasl;<sub>3</sub>, <sup>81</sup>&frasl;<sub>100</sub> and <sup>1000000</sup>&frasl;<sub>1048576</sub>.</p>\n",
+		"1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.\n",
+		"<p>1/2/2015, 1/4/2015, 3/4/2015; 2015/1/2, 2015/1/4, 2015/3/4.</p>\n"}
+
+	doTestsInlineParam(t, tests, 0, HTML_USE_SMARTYPANTS|HTML_SMARTYPANTS_FRACTIONS, HtmlRendererParameters{})
+}
diff --git a/vendor/src/github.com/russross/blackfriday/latex.go b/vendor/src/github.com/russross/blackfriday/latex.go
new file mode 100644
index 0000000..8562746
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/latex.go
@@ -0,0 +1,332 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+//
+// LaTeX rendering backend
+//
+//
+
+package blackfriday
+
+import (
+	"bytes"
+)
+
+// Latex is a type that implements the Renderer interface for LaTeX output.
+//
+// Do not create this directly, instead use the LatexRenderer function.
+type Latex struct {
+}
+
+// LatexRenderer creates and configures a Latex object, which
+// satisfies the Renderer interface.
+//
+// flags is a set of LATEX_* options ORed together (currently no such options
+// are defined).
+func LatexRenderer(flags int) Renderer {
+	return &Latex{}
+}
+
+func (options *Latex) GetFlags() int {
+	return 0
+}
+
+// render code chunks using verbatim, or listings if we have a language
+func (options *Latex) BlockCode(out *bytes.Buffer, text []byte, lang string) {
+	if lang == "" {
+		out.WriteString("\n\\begin{verbatim}\n")
+	} else {
+		out.WriteString("\n\\begin{lstlisting}[language=")
+		out.WriteString(lang)
+		out.WriteString("]\n")
+	}
+	out.Write(text)
+	if lang == "" {
+		out.WriteString("\n\\end{verbatim}\n")
+	} else {
+		out.WriteString("\n\\end{lstlisting}\n")
+	}
+}
+
+func (options *Latex) TitleBlock(out *bytes.Buffer, text []byte) {
+
+}
+
+func (options *Latex) BlockQuote(out *bytes.Buffer, text []byte) {
+	out.WriteString("\n\\begin{quotation}\n")
+	out.Write(text)
+	out.WriteString("\n\\end{quotation}\n")
+}
+
+func (options *Latex) BlockHtml(out *bytes.Buffer, text []byte) {
+	// a pretty lame thing to do...
+	out.WriteString("\n\\begin{verbatim}\n")
+	out.Write(text)
+	out.WriteString("\n\\end{verbatim}\n")
+}
+
+func (options *Latex) Header(out *bytes.Buffer, text func() bool, level int, id string) {
+	marker := out.Len()
+
+	switch level {
+	case 1:
+		out.WriteString("\n\\section{")
+	case 2:
+		out.WriteString("\n\\subsection{")
+	case 3:
+		out.WriteString("\n\\subsubsection{")
+	case 4:
+		out.WriteString("\n\\paragraph{")
+	case 5:
+		out.WriteString("\n\\subparagraph{")
+	case 6:
+		out.WriteString("\n\\textbf{")
+	}
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	out.WriteString("}\n")
+}
+
+func (options *Latex) HRule(out *bytes.Buffer) {
+	out.WriteString("\n\\HRule\n")
+}
+
+func (options *Latex) List(out *bytes.Buffer, text func() bool, flags int) {
+	marker := out.Len()
+	if flags&LIST_TYPE_ORDERED != 0 {
+		out.WriteString("\n\\begin{enumerate}\n")
+	} else {
+		out.WriteString("\n\\begin{itemize}\n")
+	}
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	if flags&LIST_TYPE_ORDERED != 0 {
+		out.WriteString("\n\\end{enumerate}\n")
+	} else {
+		out.WriteString("\n\\end{itemize}\n")
+	}
+}
+
+func (options *Latex) ListItem(out *bytes.Buffer, text []byte, flags int) {
+	out.WriteString("\n\\item ")
+	out.Write(text)
+}
+
+func (options *Latex) Paragraph(out *bytes.Buffer, text func() bool) {
+	marker := out.Len()
+	out.WriteString("\n")
+	if !text() {
+		out.Truncate(marker)
+		return
+	}
+	out.WriteString("\n")
+}
+
+func (options *Latex) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
+	out.WriteString("\n\\begin{tabular}{")
+	for _, elt := range columnData {
+		switch elt {
+		case TABLE_ALIGNMENT_LEFT:
+			out.WriteByte('l')
+		case TABLE_ALIGNMENT_RIGHT:
+			out.WriteByte('r')
+		default:
+			out.WriteByte('c')
+		}
+	}
+	out.WriteString("}\n")
+	out.Write(header)
+	out.WriteString(" \\\\\n\\hline\n")
+	out.Write(body)
+	out.WriteString("\n\\end{tabular}\n")
+}
+
+func (options *Latex) TableRow(out *bytes.Buffer, text []byte) {
+	if out.Len() > 0 {
+		out.WriteString(" \\\\\n")
+	}
+	out.Write(text)
+}
+
+func (options *Latex) TableHeaderCell(out *bytes.Buffer, text []byte, align int) {
+	if out.Len() > 0 {
+		out.WriteString(" & ")
+	}
+	out.Write(text)
+}
+
+func (options *Latex) TableCell(out *bytes.Buffer, text []byte, align int) {
+	if out.Len() > 0 {
+		out.WriteString(" & ")
+	}
+	out.Write(text)
+}
+
+// TODO: this
+func (options *Latex) Footnotes(out *bytes.Buffer, text func() bool) {
+
+}
+
+func (options *Latex) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int) {
+
+}
+
+func (options *Latex) AutoLink(out *bytes.Buffer, link []byte, kind int) {
+	out.WriteString("\\href{")
+	if kind == LINK_TYPE_EMAIL {
+		out.WriteString("mailto:")
+	}
+	out.Write(link)
+	out.WriteString("}{")
+	out.Write(link)
+	out.WriteString("}")
+}
+
+func (options *Latex) CodeSpan(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\texttt{")
+	escapeSpecialChars(out, text)
+	out.WriteString("}")
+}
+
+func (options *Latex) DoubleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\textbf{")
+	out.Write(text)
+	out.WriteString("}")
+}
+
+func (options *Latex) Emphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\textit{")
+	out.Write(text)
+	out.WriteString("}")
+}
+
+func (options *Latex) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
+	if bytes.HasPrefix(link, []byte("http://")) || bytes.HasPrefix(link, []byte("https://")) {
+		// treat it like a link
+		out.WriteString("\\href{")
+		out.Write(link)
+		out.WriteString("}{")
+		out.Write(alt)
+		out.WriteString("}")
+	} else {
+		out.WriteString("\\includegraphics{")
+		out.Write(link)
+		out.WriteString("}")
+	}
+}
+
+func (options *Latex) LineBreak(out *bytes.Buffer) {
+	out.WriteString(" \\\\\n")
+}
+
+func (options *Latex) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
+	out.WriteString("\\href{")
+	out.Write(link)
+	out.WriteString("}{")
+	out.Write(content)
+	out.WriteString("}")
+}
+
+func (options *Latex) RawHtmlTag(out *bytes.Buffer, tag []byte) {
+}
+
+func (options *Latex) TripleEmphasis(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\textbf{\\textit{")
+	out.Write(text)
+	out.WriteString("}}")
+}
+
+func (options *Latex) StrikeThrough(out *bytes.Buffer, text []byte) {
+	out.WriteString("\\sout{")
+	out.Write(text)
+	out.WriteString("}")
+}
+
+// TODO: this
+func (options *Latex) FootnoteRef(out *bytes.Buffer, ref []byte, id int) {
+
+}
+
+func needsBackslash(c byte) bool {
+	for _, r := range []byte("_{}%$&\\~") {
+		if c == r {
+			return true
+		}
+	}
+	return false
+}
+
+func escapeSpecialChars(out *bytes.Buffer, text []byte) {
+	for i := 0; i < len(text); i++ {
+		// directly copy normal characters
+		org := i
+
+		for i < len(text) && !needsBackslash(text[i]) {
+			i++
+		}
+		if i > org {
+			out.Write(text[org:i])
+		}
+
+		// escape a character
+		if i >= len(text) {
+			break
+		}
+		out.WriteByte('\\')
+		out.WriteByte(text[i])
+	}
+}
+
+func (options *Latex) Entity(out *bytes.Buffer, entity []byte) {
+	// TODO: convert this into a unicode character or something
+	out.Write(entity)
+}
+
+func (options *Latex) NormalText(out *bytes.Buffer, text []byte) {
+	escapeSpecialChars(out, text)
+}
+
+// header and footer
+func (options *Latex) DocumentHeader(out *bytes.Buffer) {
+	out.WriteString("\\documentclass{article}\n")
+	out.WriteString("\n")
+	out.WriteString("\\usepackage{graphicx}\n")
+	out.WriteString("\\usepackage{listings}\n")
+	out.WriteString("\\usepackage[margin=1in]{geometry}\n")
+	out.WriteString("\\usepackage[utf8]{inputenc}\n")
+	out.WriteString("\\usepackage{verbatim}\n")
+	out.WriteString("\\usepackage[normalem]{ulem}\n")
+	out.WriteString("\\usepackage{hyperref}\n")
+	out.WriteString("\n")
+	out.WriteString("\\hypersetup{colorlinks,%\n")
+	out.WriteString("  citecolor=black,%\n")
+	out.WriteString("  filecolor=black,%\n")
+	out.WriteString("  linkcolor=black,%\n")
+	out.WriteString("  urlcolor=black,%\n")
+	out.WriteString("  pdfstartview=FitH,%\n")
+	out.WriteString("  breaklinks=true,%\n")
+	out.WriteString("  pdfauthor={Blackfriday Markdown Processor v")
+	out.WriteString(VERSION)
+	out.WriteString("}}\n")
+	out.WriteString("\n")
+	out.WriteString("\\newcommand{\\HRule}{\\rule{\\linewidth}{0.5mm}}\n")
+	out.WriteString("\\addtolength{\\parskip}{0.5\\baselineskip}\n")
+	out.WriteString("\\parindent=0pt\n")
+	out.WriteString("\n")
+	out.WriteString("\\begin{document}\n")
+}
+
+func (options *Latex) DocumentFooter(out *bytes.Buffer) {
+	out.WriteString("\n\\end{document}\n")
+}
diff --git a/vendor/src/github.com/russross/blackfriday/markdown.go b/vendor/src/github.com/russross/blackfriday/markdown.go
new file mode 100644
index 0000000..e2cd95b
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/markdown.go
@@ -0,0 +1,838 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+//
+// Markdown parsing and processing
+//
+//
+
+// Blackfriday markdown processor.
+//
+// Translates plain text with simple formatting rules into HTML or LaTeX.
+package blackfriday
+
+import (
+	"bytes"
+	"unicode/utf8"
+)
+
+const VERSION = "1.1"
+
+// These are the supported markdown parsing extensions.
+// OR these values together to select multiple extensions.
+const (
+	EXTENSION_NO_INTRA_EMPHASIS          = 1 << iota // ignore emphasis markers inside words
+	EXTENSION_TABLES                                 // render tables
+	EXTENSION_FENCED_CODE                            // render fenced code blocks
+	EXTENSION_AUTOLINK                               // detect embedded URLs that are not explicitly marked
+	EXTENSION_STRIKETHROUGH                          // strikethrough text using ~~test~~
+	EXTENSION_LAX_HTML_BLOCKS                        // loosen up HTML block parsing rules
+	EXTENSION_SPACE_HEADERS                          // be strict about prefix header rules
+	EXTENSION_HARD_LINE_BREAK                        // translate newlines into line breaks
+	EXTENSION_TAB_SIZE_EIGHT                         // expand tabs to eight spaces instead of four
+	EXTENSION_FOOTNOTES                              // Pandoc-style footnotes
+	EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK             // No need to insert an empty line to start a (code, quote, order list, unorder list)block
+	EXTENSION_HEADER_IDS                             // specify header IDs  with {#id}
+	EXTENSION_TITLEBLOCK                             // Titleblock ala pandoc
+	EXTENSION_AUTO_HEADER_IDS                        // Create the header ID from the text
+	EXTENSION_BACKSLASH_LINE_BREAK                   // translate trailing backslashes into line breaks
+
+	commonHtmlFlags = 0 |
+		HTML_USE_XHTML |
+		HTML_USE_SMARTYPANTS |
+		HTML_SMARTYPANTS_FRACTIONS |
+		HTML_SMARTYPANTS_LATEX_DASHES
+
+	commonExtensions = 0 |
+		EXTENSION_NO_INTRA_EMPHASIS |
+		EXTENSION_TABLES |
+		EXTENSION_FENCED_CODE |
+		EXTENSION_AUTOLINK |
+		EXTENSION_STRIKETHROUGH |
+		EXTENSION_SPACE_HEADERS |
+		EXTENSION_HEADER_IDS |
+		EXTENSION_BACKSLASH_LINE_BREAK
+)
+
+// These are the possible flag values for the link renderer.
+// Only a single one of these values will be used; they are not ORed together.
+// These are mostly of interest if you are writing a new output format.
+const (
+	LINK_TYPE_NOT_AUTOLINK = iota
+	LINK_TYPE_NORMAL
+	LINK_TYPE_EMAIL
+)
+
+// These are the possible flag values for the ListItem renderer.
+// Multiple flag values may be ORed together.
+// These are mostly of interest if you are writing a new output format.
+const (
+	LIST_TYPE_ORDERED = 1 << iota
+	LIST_ITEM_CONTAINS_BLOCK
+	LIST_ITEM_BEGINNING_OF_LIST
+	LIST_ITEM_END_OF_LIST
+)
+
+// These are the possible flag values for the table cell renderer.
+// Only a single one of these values will be used; they are not ORed together.
+// These are mostly of interest if you are writing a new output format.
+const (
+	TABLE_ALIGNMENT_LEFT = 1 << iota
+	TABLE_ALIGNMENT_RIGHT
+	TABLE_ALIGNMENT_CENTER = (TABLE_ALIGNMENT_LEFT | TABLE_ALIGNMENT_RIGHT)
+)
+
+// The size of a tab stop.
+const (
+	TAB_SIZE_DEFAULT = 4
+	TAB_SIZE_EIGHT   = 8
+)
+
+// These are the tags that are recognized as HTML block tags.
+// Any of these can be included in markdown text without special escaping.
+var blockTags = map[string]bool{
+	"p":          true,
+	"dl":         true,
+	"h1":         true,
+	"h2":         true,
+	"h3":         true,
+	"h4":         true,
+	"h5":         true,
+	"h6":         true,
+	"ol":         true,
+	"ul":         true,
+	"del":        true,
+	"div":        true,
+	"ins":        true,
+	"pre":        true,
+	"form":       true,
+	"math":       true,
+	"table":      true,
+	"iframe":     true,
+	"script":     true,
+	"fieldset":   true,
+	"noscript":   true,
+	"blockquote": true,
+
+	// HTML5
+	"video":      true,
+	"aside":      true,
+	"canvas":     true,
+	"figure":     true,
+	"footer":     true,
+	"header":     true,
+	"hgroup":     true,
+	"output":     true,
+	"article":    true,
+	"section":    true,
+	"progress":   true,
+	"figcaption": true,
+}
+
+// Renderer is the rendering interface.
+// This is mostly of interest if you are implementing a new rendering format.
+//
+// When a byte slice is provided, it contains the (rendered) contents of the
+// element.
+//
+// When a callback is provided instead, it will write the contents of the
+// respective element directly to the output buffer and return true on success.
+// If the callback returns false, the rendering function should reset the
+// output buffer as though it had never been called.
+//
+// Currently Html and Latex implementations are provided
+type Renderer interface {
+	// block-level callbacks
+	BlockCode(out *bytes.Buffer, text []byte, lang string)
+	BlockQuote(out *bytes.Buffer, text []byte)
+	BlockHtml(out *bytes.Buffer, text []byte)
+	Header(out *bytes.Buffer, text func() bool, level int, id string)
+	HRule(out *bytes.Buffer)
+	List(out *bytes.Buffer, text func() bool, flags int)
+	ListItem(out *bytes.Buffer, text []byte, flags int)
+	Paragraph(out *bytes.Buffer, text func() bool)
+	Table(out *bytes.Buffer, header []byte, body []byte, columnData []int)
+	TableRow(out *bytes.Buffer, text []byte)
+	TableHeaderCell(out *bytes.Buffer, text []byte, flags int)
+	TableCell(out *bytes.Buffer, text []byte, flags int)
+	Footnotes(out *bytes.Buffer, text func() bool)
+	FootnoteItem(out *bytes.Buffer, name, text []byte, flags int)
+	TitleBlock(out *bytes.Buffer, text []byte)
+
+	// Span-level callbacks
+	AutoLink(out *bytes.Buffer, link []byte, kind int)
+	CodeSpan(out *bytes.Buffer, text []byte)
+	DoubleEmphasis(out *bytes.Buffer, text []byte)
+	Emphasis(out *bytes.Buffer, text []byte)
+	Image(out *bytes.Buffer, link []byte, title []byte, alt []byte)
+	LineBreak(out *bytes.Buffer)
+	Link(out *bytes.Buffer, link []byte, title []byte, content []byte)
+	RawHtmlTag(out *bytes.Buffer, tag []byte)
+	TripleEmphasis(out *bytes.Buffer, text []byte)
+	StrikeThrough(out *bytes.Buffer, text []byte)
+	FootnoteRef(out *bytes.Buffer, ref []byte, id int)
+
+	// Low-level callbacks
+	Entity(out *bytes.Buffer, entity []byte)
+	NormalText(out *bytes.Buffer, text []byte)
+
+	// Header and footer
+	DocumentHeader(out *bytes.Buffer)
+	DocumentFooter(out *bytes.Buffer)
+
+	GetFlags() int
+}
+
+// Callback functions for inline parsing. One such function is defined
+// for each character that triggers a response when parsing inline data.
+type inlineParser func(p *parser, out *bytes.Buffer, data []byte, offset int) int
+
+// Parser holds runtime state used by the parser.
+// This is constructed by the Markdown function.
+type parser struct {
+	r              Renderer
+	refs           map[string]*reference
+	inlineCallback [256]inlineParser
+	flags          int
+	nesting        int
+	maxNesting     int
+	insideLink     bool
+
+	// Footnotes need to be ordered as well as available to quickly check for
+	// presence. If a ref is also a footnote, it's stored both in refs and here
+	// in notes. Slice is nil if footnotes not enabled.
+	notes []*reference
+}
+
+//
+//
+// Public interface
+//
+//
+
+// MarkdownBasic is a convenience function for simple rendering.
+// It processes markdown input with no extensions enabled.
+func MarkdownBasic(input []byte) []byte {
+	// set up the HTML renderer
+	htmlFlags := HTML_USE_XHTML
+	renderer := HtmlRenderer(htmlFlags, "", "")
+
+	// set up the parser
+	extensions := 0
+
+	return Markdown(input, renderer, extensions)
+}
+
+// Call Markdown with most useful extensions enabled
+// MarkdownCommon is a convenience function for simple rendering.
+// It processes markdown input with common extensions enabled, including:
+//
+// * Smartypants processing with smart fractions and LaTeX dashes
+//
+// * Intra-word emphasis suppression
+//
+// * Tables
+//
+// * Fenced code blocks
+//
+// * Autolinking
+//
+// * Strikethrough support
+//
+// * Strict header parsing
+//
+// * Custom Header IDs
+func MarkdownCommon(input []byte) []byte {
+	// set up the HTML renderer
+	renderer := HtmlRenderer(commonHtmlFlags, "", "")
+	return Markdown(input, renderer, commonExtensions)
+}
+
+// Markdown is the main rendering function.
+// It parses and renders a block of markdown-encoded text.
+// The supplied Renderer is used to format the output, and extensions dictates
+// which non-standard extensions are enabled.
+//
+// To use the supplied Html or LaTeX renderers, see HtmlRenderer and
+// LatexRenderer, respectively.
+func Markdown(input []byte, renderer Renderer, extensions int) []byte {
+	// no point in parsing if we can't render
+	if renderer == nil {
+		return nil
+	}
+
+	// fill in the render structure
+	p := new(parser)
+	p.r = renderer
+	p.flags = extensions
+	p.refs = make(map[string]*reference)
+	p.maxNesting = 16
+	p.insideLink = false
+
+	// register inline parsers
+	p.inlineCallback['*'] = emphasis
+	p.inlineCallback['_'] = emphasis
+	if extensions&EXTENSION_STRIKETHROUGH != 0 {
+		p.inlineCallback['~'] = emphasis
+	}
+	p.inlineCallback['`'] = codeSpan
+	p.inlineCallback['\n'] = lineBreak
+	p.inlineCallback['['] = link
+	p.inlineCallback['<'] = leftAngle
+	p.inlineCallback['\\'] = escape
+	p.inlineCallback['&'] = entity
+
+	if extensions&EXTENSION_AUTOLINK != 0 {
+		p.inlineCallback[':'] = autoLink
+	}
+
+	if extensions&EXTENSION_FOOTNOTES != 0 {
+		p.notes = make([]*reference, 0)
+	}
+
+	first := firstPass(p, input)
+	second := secondPass(p, first)
+	return second
+}
+
+// first pass:
+// - extract references
+// - expand tabs
+// - normalize newlines
+// - copy everything else
+// - add missing newlines before fenced code blocks
+func firstPass(p *parser, input []byte) []byte {
+	var out bytes.Buffer
+	tabSize := TAB_SIZE_DEFAULT
+	if p.flags&EXTENSION_TAB_SIZE_EIGHT != 0 {
+		tabSize = TAB_SIZE_EIGHT
+	}
+	beg, end := 0, 0
+	lastLineWasBlank := false
+	lastFencedCodeBlockEnd := 0
+	for beg < len(input) { // iterate over lines
+		if end = isReference(p, input[beg:], tabSize); end > 0 {
+			beg += end
+		} else { // skip to the next line
+			end = beg
+			for end < len(input) && input[end] != '\n' && input[end] != '\r' {
+				end++
+			}
+
+			if p.flags&EXTENSION_FENCED_CODE != 0 {
+				// when last line was none blank and a fenced code block comes after
+				if beg >= lastFencedCodeBlockEnd {
+					if i := p.fencedCode(&out, input[beg:], false); i > 0 {
+						if !lastLineWasBlank {
+							out.WriteByte('\n') // need to inject additional linebreak
+						}
+						lastFencedCodeBlockEnd = beg + i
+					}
+				}
+				lastLineWasBlank = end == beg
+			}
+
+			// add the line body if present
+			if end > beg {
+				if end < lastFencedCodeBlockEnd { // Do not expand tabs while inside fenced code blocks.
+					out.Write(input[beg:end])
+				} else {
+					expandTabs(&out, input[beg:end], tabSize)
+				}
+			}
+			out.WriteByte('\n')
+
+			if end < len(input) && input[end] == '\r' {
+				end++
+			}
+			if end < len(input) && input[end] == '\n' {
+				end++
+			}
+
+			beg = end
+		}
+	}
+
+	// empty input?
+	if out.Len() == 0 {
+		out.WriteByte('\n')
+	}
+
+	return out.Bytes()
+}
+
+// second pass: actual rendering
+func secondPass(p *parser, input []byte) []byte {
+	var output bytes.Buffer
+
+	p.r.DocumentHeader(&output)
+	p.block(&output, input)
+
+	if p.flags&EXTENSION_FOOTNOTES != 0 && len(p.notes) > 0 {
+		p.r.Footnotes(&output, func() bool {
+			flags := LIST_ITEM_BEGINNING_OF_LIST
+			for _, ref := range p.notes {
+				var buf bytes.Buffer
+				if ref.hasBlock {
+					flags |= LIST_ITEM_CONTAINS_BLOCK
+					p.block(&buf, ref.title)
+				} else {
+					p.inline(&buf, ref.title)
+				}
+				p.r.FootnoteItem(&output, ref.link, buf.Bytes(), flags)
+				flags &^= LIST_ITEM_BEGINNING_OF_LIST | LIST_ITEM_CONTAINS_BLOCK
+			}
+
+			return true
+		})
+	}
+
+	p.r.DocumentFooter(&output)
+
+	if p.nesting != 0 {
+		panic("Nesting level did not end at zero")
+	}
+
+	return output.Bytes()
+}
+
+//
+// Link references
+//
+// This section implements support for references that (usually) appear
+// as footnotes in a document, and can be referenced anywhere in the document.
+// The basic format is:
+//
+//    [1]: http://www.google.com/ "Google"
+//    [2]: http://www.github.com/ "Github"
+//
+// Anywhere in the document, the reference can be linked by referring to its
+// label, i.e., 1 and 2 in this example, as in:
+//
+//    This library is hosted on [Github][2], a git hosting site.
+//
+// Actual footnotes as specified in Pandoc and supported by some other Markdown
+// libraries such as php-markdown are also taken care of. They look like this:
+//
+//    This sentence needs a bit of further explanation.[^note]
+//
+//    [^note]: This is the explanation.
+//
+// Footnotes should be placed at the end of the document in an ordered list.
+// Inline footnotes such as:
+//
+//    Inline footnotes^[Not supported.] also exist.
+//
+// are not yet supported.
+
+// References are parsed and stored in this struct.
+type reference struct {
+	link     []byte
+	title    []byte
+	noteId   int // 0 if not a footnote ref
+	hasBlock bool
+}
+
+// Check whether or not data starts with a reference link.
+// If so, it is parsed and stored in the list of references
+// (in the render struct).
+// Returns the number of bytes to skip to move past it,
+// or zero if the first line is not a reference.
+func isReference(p *parser, data []byte, tabSize int) int {
+	// up to 3 optional leading spaces
+	if len(data) < 4 {
+		return 0
+	}
+	i := 0
+	for i < 3 && data[i] == ' ' {
+		i++
+	}
+
+	noteId := 0
+
+	// id part: anything but a newline between brackets
+	if data[i] != '[' {
+		return 0
+	}
+	i++
+	if p.flags&EXTENSION_FOOTNOTES != 0 {
+		if data[i] == '^' {
+			// we can set it to anything here because the proper noteIds will
+			// be assigned later during the second pass. It just has to be != 0
+			noteId = 1
+			i++
+		}
+	}
+	idOffset := i
+	for i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != ']' {
+		i++
+	}
+	if i >= len(data) || data[i] != ']' {
+		return 0
+	}
+	idEnd := i
+
+	// spacer: colon (space | tab)* newline? (space | tab)*
+	i++
+	if i >= len(data) || data[i] != ':' {
+		return 0
+	}
+	i++
+	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
+		i++
+	}
+	if i < len(data) && (data[i] == '\n' || data[i] == '\r') {
+		i++
+		if i < len(data) && data[i] == '\n' && data[i-1] == '\r' {
+			i++
+		}
+	}
+	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
+		i++
+	}
+	if i >= len(data) {
+		return 0
+	}
+
+	var (
+		linkOffset, linkEnd   int
+		titleOffset, titleEnd int
+		lineEnd               int
+		raw                   []byte
+		hasBlock              bool
+	)
+
+	if p.flags&EXTENSION_FOOTNOTES != 0 && noteId != 0 {
+		linkOffset, linkEnd, raw, hasBlock = scanFootnote(p, data, i, tabSize)
+		lineEnd = linkEnd
+	} else {
+		linkOffset, linkEnd, titleOffset, titleEnd, lineEnd = scanLinkRef(p, data, i)
+	}
+	if lineEnd == 0 {
+		return 0
+	}
+
+	// a valid ref has been found
+
+	ref := &reference{
+		noteId:   noteId,
+		hasBlock: hasBlock,
+	}
+
+	if noteId > 0 {
+		// reusing the link field for the id since footnotes don't have links
+		ref.link = data[idOffset:idEnd]
+		// if footnote, it's not really a title, it's the contained text
+		ref.title = raw
+	} else {
+		ref.link = data[linkOffset:linkEnd]
+		ref.title = data[titleOffset:titleEnd]
+	}
+
+	// id matches are case-insensitive
+	id := string(bytes.ToLower(data[idOffset:idEnd]))
+
+	p.refs[id] = ref
+
+	return lineEnd
+}
+
+func scanLinkRef(p *parser, data []byte, i int) (linkOffset, linkEnd, titleOffset, titleEnd, lineEnd int) {
+	// link: whitespace-free sequence, optionally between angle brackets
+	if data[i] == '<' {
+		i++
+	}
+	linkOffset = i
+	for i < len(data) && data[i] != ' ' && data[i] != '\t' && data[i] != '\n' && data[i] != '\r' {
+		i++
+	}
+	linkEnd = i
+	if data[linkOffset] == '<' && data[linkEnd-1] == '>' {
+		linkOffset++
+		linkEnd--
+	}
+
+	// optional spacer: (space | tab)* (newline | '\'' | '"' | '(' )
+	for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
+		i++
+	}
+	if i < len(data) && data[i] != '\n' && data[i] != '\r' && data[i] != '\'' && data[i] != '"' && data[i] != '(' {
+		return
+	}
+
+	// compute end-of-line
+	if i >= len(data) || data[i] == '\r' || data[i] == '\n' {
+		lineEnd = i
+	}
+	if i+1 < len(data) && data[i] == '\r' && data[i+1] == '\n' {
+		lineEnd++
+	}
+
+	// optional (space|tab)* spacer after a newline
+	if lineEnd > 0 {
+		i = lineEnd + 1
+		for i < len(data) && (data[i] == ' ' || data[i] == '\t') {
+			i++
+		}
+	}
+
+	// optional title: any non-newline sequence enclosed in '"() alone on its line
+	if i+1 < len(data) && (data[i] == '\'' || data[i] == '"' || data[i] == '(') {
+		i++
+		titleOffset = i
+
+		// look for EOL
+		for i < len(data) && data[i] != '\n' && data[i] != '\r' {
+			i++
+		}
+		if i+1 < len(data) && data[i] == '\n' && data[i+1] == '\r' {
+			titleEnd = i + 1
+		} else {
+			titleEnd = i
+		}
+
+		// step back
+		i--
+		for i > titleOffset && (data[i] == ' ' || data[i] == '\t') {
+			i--
+		}
+		if i > titleOffset && (data[i] == '\'' || data[i] == '"' || data[i] == ')') {
+			lineEnd = titleEnd
+			titleEnd = i
+		}
+	}
+
+	return
+}
+
+// The first bit of this logic is the same as (*parser).listItem, but the rest
+// is much simpler. This function simply finds the entire block and shifts it
+// over by one tab if it is indeed a block (just returns the line if it's not).
+// blockEnd is the end of the section in the input buffer, and contents is the
+// extracted text that was shifted over one tab. It will need to be rendered at
+// the end of the document.
+func scanFootnote(p *parser, data []byte, i, indentSize int) (blockStart, blockEnd int, contents []byte, hasBlock bool) {
+	if i == 0 || len(data) == 0 {
+		return
+	}
+
+	// skip leading whitespace on first line
+	for i < len(data) && data[i] == ' ' {
+		i++
+	}
+
+	blockStart = i
+
+	// find the end of the line
+	blockEnd = i
+	for i < len(data) && data[i-1] != '\n' {
+		i++
+	}
+
+	// get working buffer
+	var raw bytes.Buffer
+
+	// put the first line into the working buffer
+	raw.Write(data[blockEnd:i])
+	blockEnd = i
+
+	// process the following lines
+	containsBlankLine := false
+
+gatherLines:
+	for blockEnd < len(data) {
+		i++
+
+		// find the end of this line
+		for i < len(data) && data[i-1] != '\n' {
+			i++
+		}
+
+		// if it is an empty line, guess that it is part of this item
+		// and move on to the next line
+		if p.isEmpty(data[blockEnd:i]) > 0 {
+			containsBlankLine = true
+			blockEnd = i
+			continue
+		}
+
+		n := 0
+		if n = isIndented(data[blockEnd:i], indentSize); n == 0 {
+			// this is the end of the block.
+			// we don't want to include this last line in the index.
+			break gatherLines
+		}
+
+		// if there were blank lines before this one, insert a new one now
+		if containsBlankLine {
+			raw.WriteByte('\n')
+			containsBlankLine = false
+		}
+
+		// get rid of that first tab, write to buffer
+		raw.Write(data[blockEnd+n : i])
+		hasBlock = true
+
+		blockEnd = i
+	}
+
+	if data[blockEnd-1] != '\n' {
+		raw.WriteByte('\n')
+	}
+
+	contents = raw.Bytes()
+
+	return
+}
+
+//
+//
+// Miscellaneous helper functions
+//
+//
+
+// Test if a character is a punctuation symbol.
+// Taken from a private function in regexp in the stdlib.
+func ispunct(c byte) bool {
+	for _, r := range []byte("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~") {
+		if c == r {
+			return true
+		}
+	}
+	return false
+}
+
+// Test if a character is a whitespace character.
+func isspace(c byte) bool {
+	return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'
+}
+
+// Test if a character is letter.
+func isletter(c byte) bool {
+	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
+}
+
+// Test if a character is a letter or a digit.
+// TODO: check when this is looking for ASCII alnum and when it should use unicode
+func isalnum(c byte) bool {
+	return (c >= '0' && c <= '9') || isletter(c)
+}
+
+// Replace tab characters with spaces, aligning to the next TAB_SIZE column.
+// always ends output with a newline
+func expandTabs(out *bytes.Buffer, line []byte, tabSize int) {
+	// first, check for common cases: no tabs, or only tabs at beginning of line
+	i, prefix := 0, 0
+	slowcase := false
+	for i = 0; i < len(line); i++ {
+		if line[i] == '\t' {
+			if prefix == i {
+				prefix++
+			} else {
+				slowcase = true
+				break
+			}
+		}
+	}
+
+	// no need to decode runes if all tabs are at the beginning of the line
+	if !slowcase {
+		for i = 0; i < prefix*tabSize; i++ {
+			out.WriteByte(' ')
+		}
+		out.Write(line[prefix:])
+		return
+	}
+
+	// the slow case: we need to count runes to figure out how
+	// many spaces to insert for each tab
+	column := 0
+	i = 0
+	for i < len(line) {
+		start := i
+		for i < len(line) && line[i] != '\t' {
+			_, size := utf8.DecodeRune(line[i:])
+			i += size
+			column++
+		}
+
+		if i > start {
+			out.Write(line[start:i])
+		}
+
+		if i >= len(line) {
+			break
+		}
+
+		for {
+			out.WriteByte(' ')
+			column++
+			if column%tabSize == 0 {
+				break
+			}
+		}
+
+		i++
+	}
+}
+
+// Find if a line counts as indented or not.
+// Returns number of characters the indent is (0 = not indented).
+func isIndented(data []byte, indentSize int) int {
+	if len(data) == 0 {
+		return 0
+	}
+	if data[0] == '\t' {
+		return 1
+	}
+	if len(data) < indentSize {
+		return 0
+	}
+	for i := 0; i < indentSize; i++ {
+		if data[i] != ' ' {
+			return 0
+		}
+	}
+	return indentSize
+}
+
+// Create a url-safe slug for fragments
+func slugify(in []byte) []byte {
+	if len(in) == 0 {
+		return in
+	}
+	out := make([]byte, 0, len(in))
+	sym := false
+
+	for _, ch := range in {
+		if isalnum(ch) {
+			sym = false
+			out = append(out, ch)
+		} else if sym {
+			continue
+		} else {
+			out = append(out, '-')
+			sym = true
+		}
+	}
+	var a, b int
+	var ch byte
+	for a, ch = range out {
+		if ch != '-' {
+			break
+		}
+	}
+	for b = len(out) - 1; b > 0; b-- {
+		if out[b] != '-' {
+			break
+		}
+	}
+	return out[a : b+1]
+}
diff --git a/vendor/src/github.com/russross/blackfriday/ref_test.go b/vendor/src/github.com/russross/blackfriday/ref_test.go
new file mode 100644
index 0000000..770439c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/ref_test.go
@@ -0,0 +1,128 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+// Markdown 1.0.3 reference tests
+//
+
+package blackfriday
+
+import (
+	"io/ioutil"
+	"path/filepath"
+	"testing"
+)
+
+func runMarkdownReference(input string, flag int) string {
+	renderer := HtmlRenderer(0, "", "")
+	return string(Markdown([]byte(input), renderer, flag))
+}
+
+func doTestsReference(t *testing.T, files []string, flag int) {
+	// catch and report panics
+	var candidate string
+	defer func() {
+		if err := recover(); err != nil {
+			t.Errorf("\npanic while processing [%#v]\n", candidate)
+		}
+	}()
+
+	for _, basename := range files {
+		filename := filepath.Join("testdata", basename+".text")
+		inputBytes, err := ioutil.ReadFile(filename)
+		if err != nil {
+			t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
+			continue
+		}
+		input := string(inputBytes)
+
+		filename = filepath.Join("testdata", basename+".html")
+		expectedBytes, err := ioutil.ReadFile(filename)
+		if err != nil {
+			t.Errorf("Couldn't open '%s', error: %v\n", filename, err)
+			continue
+		}
+		expected := string(expectedBytes)
+
+		// fmt.Fprintf(os.Stderr, "processing %s ...", filename)
+		actual := string(runMarkdownReference(input, flag))
+		if actual != expected {
+			t.Errorf("\n    [%#v]\nExpected[%#v]\nActual  [%#v]",
+				basename+".text", expected, actual)
+		}
+		// fmt.Fprintf(os.Stderr, " ok\n")
+
+		// now test every prefix of every input to check for
+		// bounds checking
+		if !testing.Short() {
+			start, max := 0, len(input)
+			for end := start + 1; end <= max; end++ {
+				candidate = input[start:end]
+				// fmt.Fprintf(os.Stderr, "  %s %d:%d/%d\n", filename, start, end, max)
+				_ = runMarkdownReference(candidate, flag)
+			}
+		}
+	}
+}
+
+func TestReference(t *testing.T) {
+	files := []string{
+		"Amps and angle encoding",
+		"Auto links",
+		"Backslash escapes",
+		"Blockquotes with code blocks",
+		"Code Blocks",
+		"Code Spans",
+		"Hard-wrapped paragraphs with list-like lines",
+		"Horizontal rules",
+		"Inline HTML (Advanced)",
+		"Inline HTML (Simple)",
+		"Inline HTML comments",
+		"Links, inline style",
+		"Links, reference style",
+		"Links, shortcut references",
+		"Literal quotes in titles",
+		"Markdown Documentation - Basics",
+		"Markdown Documentation - Syntax",
+		"Nested blockquotes",
+		"Ordered and unordered lists",
+		"Strong and em together",
+		"Tabs",
+		"Tidyness",
+	}
+	doTestsReference(t, files, 0)
+}
+
+func TestReference_EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK(t *testing.T) {
+	files := []string{
+		"Amps and angle encoding",
+		"Auto links",
+		"Backslash escapes",
+		"Blockquotes with code blocks",
+		"Code Blocks",
+		"Code Spans",
+		"Hard-wrapped paragraphs with list-like lines no empty line before block",
+		"Horizontal rules",
+		"Inline HTML (Advanced)",
+		"Inline HTML (Simple)",
+		"Inline HTML comments",
+		"Links, inline style",
+		"Links, reference style",
+		"Links, shortcut references",
+		"Literal quotes in titles",
+		"Markdown Documentation - Basics",
+		"Markdown Documentation - Syntax",
+		"Nested blockquotes",
+		"Ordered and unordered lists",
+		"Strong and em together",
+		"Tabs",
+		"Tidyness",
+	}
+	doTestsReference(t, files, EXTENSION_NO_EMPTY_LINE_BEFORE_BLOCK)
+}
diff --git a/vendor/src/github.com/russross/blackfriday/smartypants.go b/vendor/src/github.com/russross/blackfriday/smartypants.go
new file mode 100644
index 0000000..8027571
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/smartypants.go
@@ -0,0 +1,398 @@
+//
+// Blackfriday Markdown Processor
+// Available at http://github.com/russross/blackfriday
+//
+// Copyright © 2011 Russ Ross <russ@russross.com>.
+// Distributed under the Simplified BSD License.
+// See README.md for details.
+//
+
+//
+//
+// SmartyPants rendering
+//
+//
+
+package blackfriday
+
+import (
+	"bytes"
+)
+
+type smartypantsData struct {
+	inSingleQuote bool
+	inDoubleQuote bool
+}
+
+func wordBoundary(c byte) bool {
+	return c == 0 || isspace(c) || ispunct(c)
+}
+
+func tolower(c byte) byte {
+	if c >= 'A' && c <= 'Z' {
+		return c - 'A' + 'a'
+	}
+	return c
+}
+
+func isdigit(c byte) bool {
+	return c >= '0' && c <= '9'
+}
+
+func smartQuoteHelper(out *bytes.Buffer, previousChar byte, nextChar byte, quote byte, isOpen *bool) bool {
+	// edge of the buffer is likely to be a tag that we don't get to see,
+	// so we treat it like text sometimes
+
+	// enumerate all sixteen possibilities for (previousChar, nextChar)
+	// each can be one of {0, space, punct, other}
+	switch {
+	case previousChar == 0 && nextChar == 0:
+		// context is not any help here, so toggle
+		*isOpen = !*isOpen
+	case isspace(previousChar) && nextChar == 0:
+		// [ "] might be [ "<code>foo...]
+		*isOpen = true
+	case ispunct(previousChar) && nextChar == 0:
+		// [!"] hmm... could be [Run!"] or [("<code>...]
+		*isOpen = false
+	case /* isnormal(previousChar) && */ nextChar == 0:
+		// [a"] is probably a close
+		*isOpen = false
+	case previousChar == 0 && isspace(nextChar):
+		// [" ] might be [...foo</code>" ]
+		*isOpen = false
+	case isspace(previousChar) && isspace(nextChar):
+		// [ " ] context is not any help here, so toggle
+		*isOpen = !*isOpen
+	case ispunct(previousChar) && isspace(nextChar):
+		// [!" ] is probably a close
+		*isOpen = false
+	case /* isnormal(previousChar) && */ isspace(nextChar):
+		// [a" ] this is one of the easy cases
+		*isOpen = false
+	case previousChar == 0 && ispunct(nextChar):
+		// ["!] hmm... could be ["$1.95] or [</code>"!...]
+		*isOpen = false
+	case isspace(previousChar) && ispunct(nextChar):
+		// [ "!] looks more like [ "$1.95]
+		*isOpen = true
+	case ispunct(previousChar) && ispunct(nextChar):
+		// [!"!] context is not any help here, so toggle
+		*isOpen = !*isOpen
+	case /* isnormal(previousChar) && */ ispunct(nextChar):
+		// [a"!] is probably a close
+		*isOpen = false
+	case previousChar == 0 /* && isnormal(nextChar) */ :
+		// ["a] is probably an open
+		*isOpen = true
+	case isspace(previousChar) /* && isnormal(nextChar) */ :
+		// [ "a] this is one of the easy cases
+		*isOpen = true
+	case ispunct(previousChar) /* && isnormal(nextChar) */ :
+		// [!"a] is probably an open
+		*isOpen = true
+	default:
+		// [a'b] maybe a contraction?
+		*isOpen = false
+	}
+
+	out.WriteByte('&')
+	if *isOpen {
+		out.WriteByte('l')
+	} else {
+		out.WriteByte('r')
+	}
+	out.WriteByte(quote)
+	out.WriteString("quo;")
+	return true
+}
+
+func smartSingleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 2 {
+		t1 := tolower(text[1])
+
+		if t1 == '\'' {
+			nextChar := byte(0)
+			if len(text) >= 3 {
+				nextChar = text[2]
+			}
+			if smartQuoteHelper(out, previousChar, nextChar, 'd', &smrt.inDoubleQuote) {
+				return 1
+			}
+		}
+
+		if (t1 == 's' || t1 == 't' || t1 == 'm' || t1 == 'd') && (len(text) < 3 || wordBoundary(text[2])) {
+			out.WriteString("&rsquo;")
+			return 0
+		}
+
+		if len(text) >= 3 {
+			t2 := tolower(text[2])
+
+			if ((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') || (t1 == 'v' && t2 == 'e')) &&
+				(len(text) < 4 || wordBoundary(text[3])) {
+				out.WriteString("&rsquo;")
+				return 0
+			}
+		}
+	}
+
+	nextChar := byte(0)
+	if len(text) > 1 {
+		nextChar = text[1]
+	}
+	if smartQuoteHelper(out, previousChar, nextChar, 's', &smrt.inSingleQuote) {
+		return 0
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartParens(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 3 {
+		t1 := tolower(text[1])
+		t2 := tolower(text[2])
+
+		if t1 == 'c' && t2 == ')' {
+			out.WriteString("&copy;")
+			return 2
+		}
+
+		if t1 == 'r' && t2 == ')' {
+			out.WriteString("&reg;")
+			return 2
+		}
+
+		if len(text) >= 4 && t1 == 't' && t2 == 'm' && text[3] == ')' {
+			out.WriteString("&trade;")
+			return 3
+		}
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartDash(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 2 {
+		if text[1] == '-' {
+			out.WriteString("&mdash;")
+			return 1
+		}
+
+		if wordBoundary(previousChar) && wordBoundary(text[1]) {
+			out.WriteString("&ndash;")
+			return 0
+		}
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartDashLatex(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 3 && text[1] == '-' && text[2] == '-' {
+		out.WriteString("&mdash;")
+		return 2
+	}
+	if len(text) >= 2 && text[1] == '-' {
+		out.WriteString("&ndash;")
+		return 1
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartAmpVariant(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte, quote byte) int {
+	if bytes.HasPrefix(text, []byte("&quot;")) {
+		nextChar := byte(0)
+		if len(text) >= 7 {
+			nextChar = text[6]
+		}
+		if smartQuoteHelper(out, previousChar, nextChar, quote, &smrt.inDoubleQuote) {
+			return 5
+		}
+	}
+
+	if bytes.HasPrefix(text, []byte("&#0;")) {
+		return 3
+	}
+
+	out.WriteByte('&')
+	return 0
+}
+
+func smartAmp(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	return smartAmpVariant(out, smrt, previousChar, text, 'd')
+}
+
+func smartAmpAngledQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	return smartAmpVariant(out, smrt, previousChar, text, 'a')
+}
+
+func smartPeriod(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 3 && text[1] == '.' && text[2] == '.' {
+		out.WriteString("&hellip;")
+		return 2
+	}
+
+	if len(text) >= 5 && text[1] == ' ' && text[2] == '.' && text[3] == ' ' && text[4] == '.' {
+		out.WriteString("&hellip;")
+		return 4
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartBacktick(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if len(text) >= 2 && text[1] == '`' {
+		nextChar := byte(0)
+		if len(text) >= 3 {
+			nextChar = text[2]
+		}
+		if smartQuoteHelper(out, previousChar, nextChar, 'd', &smrt.inDoubleQuote) {
+			return 1
+		}
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartNumberGeneric(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {
+		// is it of the form digits/digits(word boundary)?, i.e., \d+/\d+\b
+		// note: check for regular slash (/) or fraction slash (⁄, 0x2044, or 0xe2 81 84 in utf-8)
+		//       and avoid changing dates like 1/23/2005 into fractions.
+		numEnd := 0
+		for len(text) > numEnd && isdigit(text[numEnd]) {
+			numEnd++
+		}
+		if numEnd == 0 {
+			out.WriteByte(text[0])
+			return 0
+		}
+		denStart := numEnd + 1
+		if len(text) > numEnd+3 && text[numEnd] == 0xe2 && text[numEnd+1] == 0x81 && text[numEnd+2] == 0x84 {
+			denStart = numEnd + 3
+		} else if len(text) < numEnd+2 || text[numEnd] != '/' {
+			out.WriteByte(text[0])
+			return 0
+		}
+		denEnd := denStart
+		for len(text) > denEnd && isdigit(text[denEnd]) {
+			denEnd++
+		}
+		if denEnd == denStart {
+			out.WriteByte(text[0])
+			return 0
+		}
+		if len(text) == denEnd || wordBoundary(text[denEnd]) && text[denEnd] != '/' {
+			out.WriteString("<sup>")
+			out.Write(text[:numEnd])
+			out.WriteString("</sup>&frasl;<sub>")
+			out.Write(text[denStart:denEnd])
+			out.WriteString("</sub>")
+			return denEnd - 1
+		}
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartNumber(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	if wordBoundary(previousChar) && previousChar != '/' && len(text) >= 3 {
+		if text[0] == '1' && text[1] == '/' && text[2] == '2' {
+			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' {
+				out.WriteString("&frac12;")
+				return 2
+			}
+		}
+
+		if text[0] == '1' && text[1] == '/' && text[2] == '4' {
+			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 5 && tolower(text[3]) == 't' && tolower(text[4]) == 'h') {
+				out.WriteString("&frac14;")
+				return 2
+			}
+		}
+
+		if text[0] == '3' && text[1] == '/' && text[2] == '4' {
+			if len(text) < 4 || wordBoundary(text[3]) && text[3] != '/' || (len(text) >= 6 && tolower(text[3]) == 't' && tolower(text[4]) == 'h' && tolower(text[5]) == 's') {
+				out.WriteString("&frac34;")
+				return 2
+			}
+		}
+	}
+
+	out.WriteByte(text[0])
+	return 0
+}
+
+func smartDoubleQuoteVariant(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte, quote byte) int {
+	nextChar := byte(0)
+	if len(text) > 1 {
+		nextChar = text[1]
+	}
+	if !smartQuoteHelper(out, previousChar, nextChar, quote, &smrt.inDoubleQuote) {
+		out.WriteString("&quot;")
+	}
+
+	return 0
+}
+
+func smartDoubleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	return smartDoubleQuoteVariant(out, smrt, previousChar, text, 'd')
+}
+
+func smartAngledDoubleQuote(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	return smartDoubleQuoteVariant(out, smrt, previousChar, text, 'a')
+}
+
+func smartLeftAngle(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int {
+	i := 0
+
+	for i < len(text) && text[i] != '>' {
+		i++
+	}
+
+	out.Write(text[:i+1])
+	return i
+}
+
+type smartCallback func(out *bytes.Buffer, smrt *smartypantsData, previousChar byte, text []byte) int
+
+type smartypantsRenderer [256]smartCallback
+
+func smartypants(flags int) *smartypantsRenderer {
+	r := new(smartypantsRenderer)
+	if flags&HTML_SMARTYPANTS_ANGLED_QUOTES == 0 {
+		r['"'] = smartDoubleQuote
+		r['&'] = smartAmp
+	} else {
+		r['"'] = smartAngledDoubleQuote
+		r['&'] = smartAmpAngledQuote
+	}
+	r['\''] = smartSingleQuote
+	r['('] = smartParens
+	if flags&HTML_SMARTYPANTS_LATEX_DASHES == 0 {
+		r['-'] = smartDash
+	} else {
+		r['-'] = smartDashLatex
+	}
+	r['.'] = smartPeriod
+	if flags&HTML_SMARTYPANTS_FRACTIONS == 0 {
+		r['1'] = smartNumber
+		r['3'] = smartNumber
+	} else {
+		for ch := '1'; ch <= '9'; ch++ {
+			r[ch] = smartNumberGeneric
+		}
+	}
+	r['<'] = smartLeftAngle
+	r['`'] = smartBacktick
+	return r
+}
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.html b/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.html
new file mode 100644
index 0000000..483f8ff
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.html	
@@ -0,0 +1,17 @@
+<p>AT&amp;T has an ampersand in their name.</p>
+
+<p>AT&amp;T is another way to write it.</p>
+
+<p>This &amp; that.</p>
+
+<p>4 &lt; 5.</p>
+
+<p>6 &gt; 5.</p>
+
+<p>Here's a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
+
+<p>Here's a link with an amersand in the link text: <a href="http://att.com/" title="AT&amp;T">AT&amp;T</a>.</p>
+
+<p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
+
+<p>Here's an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.text b/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.text
new file mode 100644
index 0000000..0e9527f
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Amps and angle encoding.text	
@@ -0,0 +1,21 @@
+AT&T has an ampersand in their name.
+
+AT&amp;T is another way to write it.
+
+This & that.
+
+4 < 5.
+
+6 > 5.
+
+Here's a [link] [1] with an ampersand in the URL.
+
+Here's a link with an amersand in the link text: [AT&T] [2].
+
+Here's an inline [link](/script?foo=1&bar=2).
+
+Here's an inline [link](</script?foo=1&bar=2>).
+
+
+[1]: http://example.com/?foo=1&bar=2
+[2]: http://att.com/  "AT&T"
\ No newline at end of file
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Auto links.html b/vendor/src/github.com/russross/blackfriday/testdata/Auto links.html
new file mode 100644
index 0000000..b1791e7
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Auto links.html	
@@ -0,0 +1,18 @@
+<p>Link: <a href="http://example.com/">http://example.com/</a>.</p>
+
+<p>With an ampersand: <a href="http://example.com/?foo=1&amp;bar=2">http://example.com/?foo=1&amp;bar=2</a></p>
+
+<ul>
+<li>In a list?</li>
+<li><a href="http://example.com/">http://example.com/</a></li>
+<li>It should.</li>
+</ul>
+
+<blockquote>
+<p>Blockquoted: <a href="http://example.com/">http://example.com/</a></p>
+</blockquote>
+
+<p>Auto-links should not occur here: <code>&lt;http://example.com/&gt;</code></p>
+
+<pre><code>or here: &lt;http://example.com/&gt;
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Auto links.text b/vendor/src/github.com/russross/blackfriday/testdata/Auto links.text
new file mode 100644
index 0000000..abbc488
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Auto links.text	
@@ -0,0 +1,13 @@
+Link: <http://example.com/>.
+
+With an ampersand: <http://example.com/?foo=1&bar=2>
+
+* In a list?
+* <http://example.com/>
+* It should.
+
+> Blockquoted: <http://example.com/>
+
+Auto-links should not occur here: `<http://example.com/>`
+
+	or here: <http://example.com/>
\ No newline at end of file
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.html b/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.html
new file mode 100644
index 0000000..a73c998
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.html	
@@ -0,0 +1,123 @@
+<p>These should all get escaped:</p>
+
+<p>Backslash: \</p>
+
+<p>Backtick: `</p>
+
+<p>Asterisk: *</p>
+
+<p>Underscore: _</p>
+
+<p>Left brace: {</p>
+
+<p>Right brace: }</p>
+
+<p>Left bracket: [</p>
+
+<p>Right bracket: ]</p>
+
+<p>Left paren: (</p>
+
+<p>Right paren: )</p>
+
+<p>Greater-than: &gt;</p>
+
+<p>Hash: #</p>
+
+<p>Period: .</p>
+
+<p>Bang: !</p>
+
+<p>Plus: +</p>
+
+<p>Minus: -</p>
+
+<p>Tilde: ~</p>
+
+<p>These should not, because they occur within a code block:</p>
+
+<pre><code>Backslash: \\
+
+Backtick: \`
+
+Asterisk: \*
+
+Underscore: \_
+
+Left brace: \{
+
+Right brace: \}
+
+Left bracket: \[
+
+Right bracket: \]
+
+Left paren: \(
+
+Right paren: \)
+
+Greater-than: \&gt;
+
+Hash: \#
+
+Period: \.
+
+Bang: \!
+
+Plus: \+
+
+Minus: \-
+
+Tilde: \~
+</code></pre>
+
+<p>Nor should these, which occur in code spans:</p>
+
+<p>Backslash: <code>\\</code></p>
+
+<p>Backtick: <code>\`</code></p>
+
+<p>Asterisk: <code>\*</code></p>
+
+<p>Underscore: <code>\_</code></p>
+
+<p>Left brace: <code>\{</code></p>
+
+<p>Right brace: <code>\}</code></p>
+
+<p>Left bracket: <code>\[</code></p>
+
+<p>Right bracket: <code>\]</code></p>
+
+<p>Left paren: <code>\(</code></p>
+
+<p>Right paren: <code>\)</code></p>
+
+<p>Greater-than: <code>\&gt;</code></p>
+
+<p>Hash: <code>\#</code></p>
+
+<p>Period: <code>\.</code></p>
+
+<p>Bang: <code>\!</code></p>
+
+<p>Plus: <code>\+</code></p>
+
+<p>Minus: <code>\-</code></p>
+
+<p>Tilde: <code>\~</code></p>
+
+<p>These should get escaped, even though they're matching pairs for
+other Markdown constructs:</p>
+
+<p>*asterisks*</p>
+
+<p>_underscores_</p>
+
+<p>`backticks`</p>
+
+<p>This is a code span with a literal backslash-backtick sequence: <code>\`</code></p>
+
+<p>This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.</p>
+
+<p>This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.text b/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.text
new file mode 100644
index 0000000..04c20bd
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Backslash escapes.text	
@@ -0,0 +1,126 @@
+These should all get escaped:
+
+Backslash: \\
+
+Backtick: \`
+
+Asterisk: \*
+
+Underscore: \_
+
+Left brace: \{
+
+Right brace: \}
+
+Left bracket: \[
+
+Right bracket: \]
+
+Left paren: \(
+
+Right paren: \)
+
+Greater-than: \>
+
+Hash: \#
+
+Period: \.
+
+Bang: \!
+
+Plus: \+
+
+Minus: \-
+
+Tilde: \~
+
+
+
+These should not, because they occur within a code block:
+
+	Backslash: \\
+
+	Backtick: \`
+
+	Asterisk: \*
+
+	Underscore: \_
+
+	Left brace: \{
+
+	Right brace: \}
+
+	Left bracket: \[
+
+	Right bracket: \]
+
+	Left paren: \(
+
+	Right paren: \)
+
+	Greater-than: \>
+
+	Hash: \#
+
+	Period: \.
+
+	Bang: \!
+
+	Plus: \+
+
+	Minus: \-
+
+	Tilde: \~
+
+
+Nor should these, which occur in code spans:
+
+Backslash: `\\`
+
+Backtick: `` \` ``
+
+Asterisk: `\*`
+
+Underscore: `\_`
+
+Left brace: `\{`
+
+Right brace: `\}`
+
+Left bracket: `\[`
+
+Right bracket: `\]`
+
+Left paren: `\(`
+
+Right paren: `\)`
+
+Greater-than: `\>`
+
+Hash: `\#`
+
+Period: `\.`
+
+Bang: `\!`
+
+Plus: `\+`
+
+Minus: `\-`
+
+Tilde: `\~`
+
+
+These should get escaped, even though they're matching pairs for
+other Markdown constructs:
+
+\*asterisks\*
+
+\_underscores\_
+
+\`backticks\`
+
+This is a code span with a literal backslash-backtick sequence: `` \` ``
+
+This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
+
+This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.html b/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.html
new file mode 100644
index 0000000..360fa9b
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.html	
@@ -0,0 +1,15 @@
+<blockquote>
+<p>Example:</p>
+
+<pre><code>sub status {
+    print &quot;working&quot;;
+}
+</code></pre>
+
+<p>Or:</p>
+
+<pre><code>sub status {
+    return &quot;working&quot;;
+}
+</code></pre>
+</blockquote>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.text b/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.text
new file mode 100644
index 0000000..c31d171
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Blockquotes with code blocks.text	
@@ -0,0 +1,11 @@
+> Example:
+> 
+>     sub status {
+>         print "working";
+>     }
+> 
+> Or:
+> 
+>     sub status {
+>         return "working";
+>     }
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.html b/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.html
new file mode 100644
index 0000000..32703f5
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.html	
@@ -0,0 +1,18 @@
+<pre><code>code block on the first line
+</code></pre>
+
+<p>Regular text.</p>
+
+<pre><code>code block indented by spaces
+</code></pre>
+
+<p>Regular text.</p>
+
+<pre><code>the lines in this block  
+all contain trailing spaces  
+</code></pre>
+
+<p>Regular Text.</p>
+
+<pre><code>code block on the last line
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.text b/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.text
new file mode 100644
index 0000000..b54b092
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Code Blocks.text	
@@ -0,0 +1,14 @@
+	code block on the first line
+	
+Regular text.
+
+    code block indented by spaces
+
+Regular text.
+
+	the lines in this block  
+	all contain trailing spaces  
+
+Regular Text.
+
+	code block on the last line
\ No newline at end of file
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.html b/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.html
new file mode 100644
index 0000000..ef85f95
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.html	
@@ -0,0 +1,5 @@
+<p><code>&lt;test a=&quot;</code> content of attribute <code>&quot;&gt;</code></p>
+
+<p>Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span></p>
+
+<p>Here's how you put <code>`backticks`</code> in a code span.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.text b/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.text
new file mode 100644
index 0000000..750a197
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Code Spans.text	
@@ -0,0 +1,6 @@
+`<test a="` content of attribute `">`
+
+Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
+
+Here's how you put `` `backticks` `` in a code span.
+
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.html b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.html
new file mode 100644
index 0000000..fc25319
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.html	
@@ -0,0 +1,14 @@
+<p>In Markdown 1.0.0 and earlier. Version</p>
+
+<ol>
+<li>This line turns into a list item.
+Because a hard-wrapped line in the
+middle of a paragraph looked like a
+list item.</li>
+</ol>
+
+<p>Here's one with a bullet.</p>
+
+<ul>
+<li>criminey.</li>
+</ul>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.text b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.text
new file mode 100644
index 0000000..f8a5b27
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines no empty line before block.text	
@@ -0,0 +1,8 @@
+In Markdown 1.0.0 and earlier. Version
+8. This line turns into a list item.
+Because a hard-wrapped line in the
+middle of a paragraph looked like a
+list item.
+
+Here's one with a bullet.
+* criminey.
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.html b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.html
new file mode 100644
index 0000000..e21ac79
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.html	
@@ -0,0 +1,8 @@
+<p>In Markdown 1.0.0 and earlier. Version
+8. This line turns into a list item.
+Because a hard-wrapped line in the
+middle of a paragraph looked like a
+list item.</p>
+
+<p>Here's one with a bullet.
+* criminey.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.text b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.text
new file mode 100644
index 0000000..f8a5b27
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Hard-wrapped paragraphs with list-like lines.text	
@@ -0,0 +1,8 @@
+In Markdown 1.0.0 and earlier. Version
+8. This line turns into a list item.
+Because a hard-wrapped line in the
+middle of a paragraph looked like a
+list item.
+
+Here's one with a bullet.
+* criminey.
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.html b/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.html
new file mode 100644
index 0000000..e60d4ba
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.html	
@@ -0,0 +1,71 @@
+<p>Dashes:</p>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>---
+</code></pre>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>- - -
+</code></pre>
+
+<p>Asterisks:</p>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>***
+</code></pre>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>* * *
+</code></pre>
+
+<p>Underscores:</p>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>___
+</code></pre>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<hr>
+
+<pre><code>_ _ _
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.text b/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.text
new file mode 100644
index 0000000..1594bda
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Horizontal rules.text	
@@ -0,0 +1,67 @@
+Dashes:
+
+---
+
+ ---
+ 
+  ---
+
+   ---
+
+	---
+
+- - -
+
+ - - -
+ 
+  - - -
+
+   - - -
+
+	- - -
+
+
+Asterisks:
+
+***
+
+ ***
+ 
+  ***
+
+   ***
+
+	***
+
+* * *
+
+ * * *
+ 
+  * * *
+
+   * * *
+
+	* * *
+
+
+Underscores:
+
+___
+
+ ___
+ 
+  ___
+
+   ___
+
+    ___
+
+_ _ _
+
+ _ _ _
+ 
+  _ _ _
+
+   _ _ _
+
+    _ _ _
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).html b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).html
new file mode 100644
index 0000000..3af9caf
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).html	
@@ -0,0 +1,15 @@
+<p>Simple block on one line:</p>
+
+<div>foo</div>
+
+<p>And nested without indentation:</p>
+
+<div>
+<div>
+<div>
+foo
+</div>
+<div style=">"/>
+</div>
+<div>bar</div>
+</div>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).text b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).text
new file mode 100644
index 0000000..86b7206
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Advanced).text	
@@ -0,0 +1,15 @@
+Simple block on one line:
+
+<div>foo</div>
+
+And nested without indentation:
+
+<div>
+<div>
+<div>
+foo
+</div>
+<div style=">"/>
+</div>
+<div>bar</div>
+</div>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).html b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).html
new file mode 100644
index 0000000..6bf78f8
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).html	
@@ -0,0 +1,72 @@
+<p>Here's a simple block:</p>
+
+<div>
+    foo
+</div>
+
+<p>This should be a code block, though:</p>
+
+<pre><code>&lt;div&gt;
+    foo
+&lt;/div&gt;
+</code></pre>
+
+<p>As should this:</p>
+
+<pre><code>&lt;div&gt;foo&lt;/div&gt;
+</code></pre>
+
+<p>Now, nested:</p>
+
+<div>
+    <div>
+        <div>
+            foo
+        </div>
+    </div>
+</div>
+
+<p>This should just be an HTML comment:</p>
+
+<!-- Comment -->
+
+<p>Multiline:</p>
+
+<!--
+Blah
+Blah
+-->
+
+<p>Code block:</p>
+
+<pre><code>&lt;!-- Comment --&gt;
+</code></pre>
+
+<p>Just plain comment, with trailing spaces on the line:</p>
+
+<!-- foo -->   
+
+<p>Code:</p>
+
+<pre><code>&lt;hr /&gt;
+</code></pre>
+
+<p>Hr's:</p>
+
+<hr>
+
+<hr/>
+
+<hr />
+
+<hr>   
+
+<hr/>  
+
+<hr /> 
+
+<hr class="foo" id="bar" />
+
+<hr class="foo" id="bar"/>
+
+<hr class="foo" id="bar" >
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).text b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).text
new file mode 100644
index 0000000..14aa2dc
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML (Simple).text	
@@ -0,0 +1,69 @@
+Here's a simple block:
+
+<div>
+	foo
+</div>
+
+This should be a code block, though:
+
+	<div>
+		foo
+	</div>
+
+As should this:
+
+	<div>foo</div>
+
+Now, nested:
+
+<div>
+	<div>
+		<div>
+			foo
+		</div>
+	</div>
+</div>
+
+This should just be an HTML comment:
+
+<!-- Comment -->
+
+Multiline:
+
+<!--
+Blah
+Blah
+-->
+
+Code block:
+
+	<!-- Comment -->
+
+Just plain comment, with trailing spaces on the line:
+
+<!-- foo -->   
+
+Code:
+
+	<hr />
+	
+Hr's:
+
+<hr>
+
+<hr/>
+
+<hr />
+
+<hr>   
+
+<hr/>  
+
+<hr /> 
+
+<hr class="foo" id="bar" />
+
+<hr class="foo" id="bar"/>
+
+<hr class="foo" id="bar" >
+
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.html b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.html
new file mode 100644
index 0000000..3f167a1
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.html	
@@ -0,0 +1,13 @@
+<p>Paragraph one.</p>
+
+<!-- This is a simple comment -->
+
+<!--
+    This is another comment.
+-->
+
+<p>Paragraph two.</p>
+
+<!-- one comment block -- -- with two comments -->
+
+<p>The end.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.text b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.text
new file mode 100644
index 0000000..41d830d
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Inline HTML comments.text	
@@ -0,0 +1,13 @@
+Paragraph one.
+
+<!-- This is a simple comment -->
+
+<!--
+	This is another comment.
+-->
+
+Paragraph two.
+
+<!-- one comment block -- -- with two comments -->
+
+The end.
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.html b/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.html
new file mode 100644
index 0000000..5802f2d
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.html	
@@ -0,0 +1,11 @@
+<p>Just a <a href="/url/">URL</a>.</p>
+
+<p><a href="/url/" title="title">URL and title</a>.</p>
+
+<p><a href="/url/" title="title preceded by two spaces">URL and title</a>.</p>
+
+<p><a href="/url/" title="title preceded by a tab">URL and title</a>.</p>
+
+<p><a href="/url/" title="title has spaces afterward">URL and title</a>.</p>
+
+<p>[Empty]().</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.text b/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.text
new file mode 100644
index 0000000..09017a9
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, inline style.text	
@@ -0,0 +1,12 @@
+Just a [URL](/url/).
+
+[URL and title](/url/ "title").
+
+[URL and title](/url/  "title preceded by two spaces").
+
+[URL and title](/url/	"title preceded by a tab").
+
+[URL and title](/url/ "title has spaces afterward"  ).
+
+
+[Empty]().
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.html b/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.html
new file mode 100644
index 0000000..bebefde
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.html	
@@ -0,0 +1,52 @@
+<p>Foo <a href="/url/" title="Title">bar</a>.</p>
+
+<p>Foo <a href="/url/" title="Title">bar</a>.</p>
+
+<p>Foo <a href="/url/" title="Title">bar</a>.</p>
+
+<p>With <a href="/url/">embedded [brackets]</a>.</p>
+
+<p>Indented <a href="/url">once</a>.</p>
+
+<p>Indented <a href="/url">twice</a>.</p>
+
+<p>Indented <a href="/url">thrice</a>.</p>
+
+<p>Indented [four][] times.</p>
+
+<pre><code>[four]: /url
+</code></pre>
+
+<hr>
+
+<p><a href="foo">this</a> should work</p>
+
+<p>So should <a href="foo">this</a>.</p>
+
+<p>And <a href="foo">this</a>.</p>
+
+<p>And <a href="foo">this</a>.</p>
+
+<p>And <a href="foo">this</a>.</p>
+
+<p>But not [that] [].</p>
+
+<p>Nor [that][].</p>
+
+<p>Nor [that].</p>
+
+<p>[Something in brackets like <a href="foo">this</a> should work]</p>
+
+<p>[Same with <a href="foo">this</a>.]</p>
+
+<p>In this case, <a href="/somethingelse/">this</a> points to something else.</p>
+
+<p>Backslashing should suppress [this] and [this].</p>
+
+<hr>
+
+<p>Here's one where the <a href="/url/">link
+breaks</a> across lines.</p>
+
+<p>Here's another where the <a href="/url/">link
+breaks</a> across lines, but with a line-ending space.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.text b/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.text
new file mode 100644
index 0000000..341ec88
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, reference style.text	
@@ -0,0 +1,71 @@
+Foo [bar] [1].
+
+Foo [bar][1].
+
+Foo [bar]
+[1].
+
+[1]: /url/  "Title"
+
+
+With [embedded [brackets]] [b].
+
+
+Indented [once][].
+
+Indented [twice][].
+
+Indented [thrice][].
+
+Indented [four][] times.
+
+ [once]: /url
+
+  [twice]: /url
+
+   [thrice]: /url
+
+    [four]: /url
+
+
+[b]: /url/
+
+* * *
+
+[this] [this] should work
+
+So should [this][this].
+
+And [this] [].
+
+And [this][].
+
+And [this].
+
+But not [that] [].
+
+Nor [that][].
+
+Nor [that].
+
+[Something in brackets like [this][] should work]
+
+[Same with [this].]
+
+In this case, [this](/somethingelse/) points to something else.
+
+Backslashing should suppress \[this] and [this\].
+
+[this]: foo
+
+
+* * *
+
+Here's one where the [link
+breaks] across lines.
+
+Here's another where the [link 
+breaks] across lines, but with a line-ending space.
+
+
+[link breaks]: /url/
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.html b/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.html
new file mode 100644
index 0000000..0b5e1d6
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.html	
@@ -0,0 +1,9 @@
+<p>This is the <a href="/simple">simple case</a>.</p>
+
+<p>This one has a <a href="/foo">line
+break</a>.</p>
+
+<p>This one has a <a href="/foo">line
+break</a> with a line-ending space.</p>
+
+<p><a href="/that">this</a> and the <a href="/other">other</a></p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.text b/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.text
new file mode 100644
index 0000000..8c44c98
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Links, shortcut references.text	
@@ -0,0 +1,20 @@
+This is the [simple case].
+
+[simple case]: /simple
+
+
+
+This one has a [line
+break].
+
+This one has a [line 
+break] with a line-ending space.
+
+[line break]: /foo
+
+
+[this] [that] and the [other]
+
+[this]: /this
+[that]: /that
+[other]: /other
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.html b/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.html
new file mode 100644
index 0000000..611c1ac
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.html	
@@ -0,0 +1,3 @@
+<p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
+
+<p>Foo <a href="/url/" title="Title with &quot;quotes&quot; inside">bar</a>.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.text b/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.text
new file mode 100644
index 0000000..29d0e42
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Literal quotes in titles.text	
@@ -0,0 +1,7 @@
+Foo [bar][].
+
+Foo [bar](/url/ "Title with "quotes" inside").
+
+
+  [bar]: /url/ "Title with "quotes" inside"
+
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.html b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.html
new file mode 100644
index 0000000..ea3a61c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.html	
@@ -0,0 +1,314 @@
+<h1>Markdown: Basics</h1>
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a class="selected" title="Markdown Basics">Basics</a></li>
+    <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+<h2>Getting the Gist of Markdown's Formatting Syntax</h2>
+
+<p>This page offers a brief overview of what it's like to use Markdown.
+The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for
+every feature, but Markdown should be very easy to pick up simply by
+looking at a few examples of it in action. The examples on this page
+are written in a before/after style, showing example syntax and the
+HTML output produced by Markdown.</p>
+
+<p>It's also helpful to simply try Markdown out; the <a href="/projects/markdown/dingus" title="Markdown Dingus">Dingus</a> is a
+web application that allows you type your own Markdown-formatted text
+and translate it to XHTML.</p>
+
+<p><strong>Note:</strong> This document is itself written using Markdown; you
+can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p>
+
+<h2>Paragraphs, Headers, Blockquotes</h2>
+
+<p>A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
+
+<p>Markdown offers two styles of headers: <em>Setext</em> and <em>atx</em>.
+Setext-style headers for <code>&lt;h1&gt;</code> and <code>&lt;h2&gt;</code> are created by
+&quot;underlining&quot; with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively.
+To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the
+beginning of the line -- the number of hashes equals the resulting
+HTML header level.</p>
+
+<p>Blockquotes are indicated using email-style '<code>&gt;</code>' angle brackets.</p>
+
+<p>Markdown:</p>
+
+<pre><code>A First Level Header
+====================
+
+A Second Level Header
+---------------------
+
+Now is the time for all good men to come to
+the aid of their country. This is just a
+regular paragraph.
+
+The quick brown fox jumped over the lazy
+dog's back.
+
+### Header 3
+
+&gt; This is a blockquote.
+&gt; 
+&gt; This is the second paragraph in the blockquote.
+&gt;
+&gt; ## This is an H2 in a blockquote
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;h1&gt;A First Level Header&lt;/h1&gt;
+
+&lt;h2&gt;A Second Level Header&lt;/h2&gt;
+
+&lt;p&gt;Now is the time for all good men to come to
+the aid of their country. This is just a
+regular paragraph.&lt;/p&gt;
+
+&lt;p&gt;The quick brown fox jumped over the lazy
+dog's back.&lt;/p&gt;
+
+&lt;h3&gt;Header 3&lt;/h3&gt;
+
+&lt;blockquote&gt;
+    &lt;p&gt;This is a blockquote.&lt;/p&gt;
+
+    &lt;p&gt;This is the second paragraph in the blockquote.&lt;/p&gt;
+
+    &lt;h2&gt;This is an H2 in a blockquote&lt;/h2&gt;
+&lt;/blockquote&gt;
+</code></pre>
+
+<h3>Phrase Emphasis</h3>
+
+<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p>
+
+<p>Markdown:</p>
+
+<pre><code>Some of these words *are emphasized*.
+Some of these words _are emphasized also_.
+
+Use two asterisks for **strong emphasis**.
+Or, if you prefer, __use two underscores instead__.
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;Some of these words &lt;em&gt;are emphasized&lt;/em&gt;.
+Some of these words &lt;em&gt;are emphasized also&lt;/em&gt;.&lt;/p&gt;
+
+&lt;p&gt;Use two asterisks for &lt;strong&gt;strong emphasis&lt;/strong&gt;.
+Or, if you prefer, &lt;strong&gt;use two underscores instead&lt;/strong&gt;.&lt;/p&gt;
+</code></pre>
+
+<h2>Lists</h2>
+
+<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
+<code>+</code>, and <code>-</code>) as list markers. These three markers are
+interchangable; this:</p>
+
+<pre><code>*   Candy.
+*   Gum.
+*   Booze.
+</code></pre>
+
+<p>this:</p>
+
+<pre><code>+   Candy.
++   Gum.
++   Booze.
+</code></pre>
+
+<p>and this:</p>
+
+<pre><code>-   Candy.
+-   Gum.
+-   Booze.
+</code></pre>
+
+<p>all produce the same output:</p>
+
+<pre><code>&lt;ul&gt;
+&lt;li&gt;Candy.&lt;/li&gt;
+&lt;li&gt;Gum.&lt;/li&gt;
+&lt;li&gt;Booze.&lt;/li&gt;
+&lt;/ul&gt;
+</code></pre>
+
+<p>Ordered (numbered) lists use regular numbers, followed by periods, as
+list markers:</p>
+
+<pre><code>1.  Red
+2.  Green
+3.  Blue
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;ol&gt;
+&lt;li&gt;Red&lt;/li&gt;
+&lt;li&gt;Green&lt;/li&gt;
+&lt;li&gt;Blue&lt;/li&gt;
+&lt;/ol&gt;
+</code></pre>
+
+<p>If you put blank lines between items, you'll get <code>&lt;p&gt;</code> tags for the
+list item text. You can create multi-paragraph list items by indenting
+the paragraphs by 4 spaces or 1 tab:</p>
+
+<pre><code>*   A list item.
+
+    With multiple paragraphs.
+
+*   Another item in the list.
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;ul&gt;
+&lt;li&gt;&lt;p&gt;A list item.&lt;/p&gt;
+&lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
+&lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
+&lt;/ul&gt;
+</code></pre>
+
+<h3>Links</h3>
+
+<p>Markdown supports two styles for creating links: <em>inline</em> and
+<em>reference</em>. With both styles, you use square brackets to delimit the
+text you want to turn into a link.</p>
+
+<p>Inline-style links use parentheses immediately after the link text.
+For example:</p>
+
+<pre><code>This is an [example link](http://example.com/).
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;This is an &lt;a href=&quot;http://example.com/&quot;&gt;
+example link&lt;/a&gt;.&lt;/p&gt;
+</code></pre>
+
+<p>Optionally, you may include a title attribute in the parentheses:</p>
+
+<pre><code>This is an [example link](http://example.com/ &quot;With a Title&quot;).
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;This is an &lt;a href=&quot;http://example.com/&quot; title=&quot;With a Title&quot;&gt;
+example link&lt;/a&gt;.&lt;/p&gt;
+</code></pre>
+
+<p>Reference-style links allow you to refer to your links by names, which
+you define elsewhere in your document:</p>
+
+<pre><code>I get 10 times more traffic from [Google][1] than from
+[Yahoo][2] or [MSN][3].
+
+[1]: http://google.com/        &quot;Google&quot;
+[2]: http://search.yahoo.com/  &quot;Yahoo Search&quot;
+[3]: http://search.msn.com/    &quot;MSN Search&quot;
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;I get 10 times more traffic from &lt;a href=&quot;http://google.com/&quot;
+title=&quot;Google&quot;&gt;Google&lt;/a&gt; than from &lt;a href=&quot;http://search.yahoo.com/&quot;
+title=&quot;Yahoo Search&quot;&gt;Yahoo&lt;/a&gt; or &lt;a href=&quot;http://search.msn.com/&quot;
+title=&quot;MSN Search&quot;&gt;MSN&lt;/a&gt;.&lt;/p&gt;
+</code></pre>
+
+<p>The title attribute is optional. Link names may contain letters,
+numbers and spaces, but are <em>not</em> case sensitive:</p>
+
+<pre><code>I start my morning with a cup of coffee and
+[The New York Times][NY Times].
+
+[ny times]: http://www.nytimes.com/
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;I start my morning with a cup of coffee and
+&lt;a href=&quot;http://www.nytimes.com/&quot;&gt;The New York Times&lt;/a&gt;.&lt;/p&gt;
+</code></pre>
+
+<h3>Images</h3>
+
+<p>Image syntax is very much like link syntax.</p>
+
+<p>Inline (titles are optional):</p>
+
+<pre><code>![alt text](/path/to/img.jpg &quot;Title&quot;)
+</code></pre>
+
+<p>Reference-style:</p>
+
+<pre><code>![alt text][id]
+
+[id]: /path/to/img.jpg &quot;Title&quot;
+</code></pre>
+
+<p>Both of the above examples produce the same output:</p>
+
+<pre><code>&lt;img src=&quot;/path/to/img.jpg&quot; alt=&quot;alt text&quot; title=&quot;Title&quot; /&gt;
+</code></pre>
+
+<h3>Code</h3>
+
+<p>In a regular paragraph, you can create code span by wrapping text in
+backtick quotes. Any ampersands (<code>&amp;</code>) and angle brackets (<code>&lt;</code> or
+<code>&gt;</code>) will automatically be translated into HTML entities. This makes
+it easy to use Markdown to write about HTML example code:</p>
+
+<pre><code>I strongly recommend against using any `&lt;blink&gt;` tags.
+
+I wish SmartyPants used named entities like `&amp;mdash;`
+instead of decimal-encoded entites like `&amp;#8212;`.
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;I strongly recommend against using any
+&lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
+
+&lt;p&gt;I wish SmartyPants used named entities like
+&lt;code&gt;&amp;amp;mdash;&lt;/code&gt; instead of decimal-encoded
+entites like &lt;code&gt;&amp;amp;#8212;&lt;/code&gt;.&lt;/p&gt;
+</code></pre>
+
+<p>To specify an entire block of pre-formatted code, indent every line of
+the block by 4 spaces or 1 tab. Just like with code spans, <code>&amp;</code>, <code>&lt;</code>,
+and <code>&gt;</code> characters will be escaped automatically.</p>
+
+<p>Markdown:</p>
+
+<pre><code>If you want your page to validate under XHTML 1.0 Strict,
+you've got to put paragraph tags in your blockquotes:
+
+    &lt;blockquote&gt;
+        &lt;p&gt;For example.&lt;/p&gt;
+    &lt;/blockquote&gt;
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;If you want your page to validate under XHTML 1.0 Strict,
+you've got to put paragraph tags in your blockquotes:&lt;/p&gt;
+
+&lt;pre&gt;&lt;code&gt;&amp;lt;blockquote&amp;gt;
+    &amp;lt;p&amp;gt;For example.&amp;lt;/p&amp;gt;
+&amp;lt;/blockquote&amp;gt;
+&lt;/code&gt;&lt;/pre&gt;
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.text b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.text
new file mode 100644
index 0000000..486055c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Basics.text	
@@ -0,0 +1,306 @@
+Markdown: Basics
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a class="selected" title="Markdown Basics">Basics</a></li>
+    <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+Getting the Gist of Markdown's Formatting Syntax
+------------------------------------------------
+
+This page offers a brief overview of what it's like to use Markdown.
+The [syntax page] [s] provides complete, detailed documentation for
+every feature, but Markdown should be very easy to pick up simply by
+looking at a few examples of it in action. The examples on this page
+are written in a before/after style, showing example syntax and the
+HTML output produced by Markdown.
+
+It's also helpful to simply try Markdown out; the [Dingus] [d] is a
+web application that allows you type your own Markdown-formatted text
+and translate it to XHTML.
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL] [src].
+
+  [s]: /projects/markdown/syntax  "Markdown Syntax"
+  [d]: /projects/markdown/dingus  "Markdown Dingus"
+  [src]: /projects/markdown/basics.text
+
+
+## Paragraphs, Headers, Blockquotes ##
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+Markdown offers two styles of headers: *Setext* and *atx*.
+Setext-style headers for `<h1>` and `<h2>` are created by
+"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
+To create an atx-style header, you put 1-6 hash marks (`#`) at the
+beginning of the line -- the number of hashes equals the resulting
+HTML header level.
+
+Blockquotes are indicated using email-style '`>`' angle brackets.
+
+Markdown:
+
+    A First Level Header
+    ====================
+    
+    A Second Level Header
+    ---------------------
+
+    Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.
+
+    The quick brown fox jumped over the lazy
+    dog's back.
+    
+    ### Header 3
+
+    > This is a blockquote.
+    > 
+    > This is the second paragraph in the blockquote.
+    >
+    > ## This is an H2 in a blockquote
+
+
+Output:
+
+    <h1>A First Level Header</h1>
+    
+    <h2>A Second Level Header</h2>
+    
+    <p>Now is the time for all good men to come to
+    the aid of their country. This is just a
+    regular paragraph.</p>
+    
+    <p>The quick brown fox jumped over the lazy
+    dog's back.</p>
+    
+    <h3>Header 3</h3>
+    
+    <blockquote>
+        <p>This is a blockquote.</p>
+        
+        <p>This is the second paragraph in the blockquote.</p>
+        
+        <h2>This is an H2 in a blockquote</h2>
+    </blockquote>
+
+
+
+### Phrase Emphasis ###
+
+Markdown uses asterisks and underscores to indicate spans of emphasis.
+
+Markdown:
+
+    Some of these words *are emphasized*.
+    Some of these words _are emphasized also_.
+    
+    Use two asterisks for **strong emphasis**.
+    Or, if you prefer, __use two underscores instead__.
+
+Output:
+
+    <p>Some of these words <em>are emphasized</em>.
+    Some of these words <em>are emphasized also</em>.</p>
+    
+    <p>Use two asterisks for <strong>strong emphasis</strong>.
+    Or, if you prefer, <strong>use two underscores instead</strong>.</p>
+   
+
+
+## Lists ##
+
+Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
+`+`, and `-`) as list markers. These three markers are
+interchangable; this:
+
+    *   Candy.
+    *   Gum.
+    *   Booze.
+
+this:
+
+    +   Candy.
+    +   Gum.
+    +   Booze.
+
+and this:
+
+    -   Candy.
+    -   Gum.
+    -   Booze.
+
+all produce the same output:
+
+    <ul>
+    <li>Candy.</li>
+    <li>Gum.</li>
+    <li>Booze.</li>
+    </ul>
+
+Ordered (numbered) lists use regular numbers, followed by periods, as
+list markers:
+
+    1.  Red
+    2.  Green
+    3.  Blue
+
+Output:
+
+    <ol>
+    <li>Red</li>
+    <li>Green</li>
+    <li>Blue</li>
+    </ol>
+
+If you put blank lines between items, you'll get `<p>` tags for the
+list item text. You can create multi-paragraph list items by indenting
+the paragraphs by 4 spaces or 1 tab:
+
+    *   A list item.
+    
+        With multiple paragraphs.
+
+    *   Another item in the list.
+
+Output:
+
+    <ul>
+    <li><p>A list item.</p>
+    <p>With multiple paragraphs.</p></li>
+    <li><p>Another item in the list.</p></li>
+    </ul>
+    
+
+
+### Links ###
+
+Markdown supports two styles for creating links: *inline* and
+*reference*. With both styles, you use square brackets to delimit the
+text you want to turn into a link.
+
+Inline-style links use parentheses immediately after the link text.
+For example:
+
+    This is an [example link](http://example.com/).
+
+Output:
+
+    <p>This is an <a href="http://example.com/">
+    example link</a>.</p>
+
+Optionally, you may include a title attribute in the parentheses:
+
+    This is an [example link](http://example.com/ "With a Title").
+
+Output:
+
+    <p>This is an <a href="http://example.com/" title="With a Title">
+    example link</a>.</p>
+
+Reference-style links allow you to refer to your links by names, which
+you define elsewhere in your document:
+
+    I get 10 times more traffic from [Google][1] than from
+    [Yahoo][2] or [MSN][3].
+
+    [1]: http://google.com/        "Google"
+    [2]: http://search.yahoo.com/  "Yahoo Search"
+    [3]: http://search.msn.com/    "MSN Search"
+
+Output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from <a href="http://search.yahoo.com/"
+    title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
+    title="MSN Search">MSN</a>.</p>
+
+The title attribute is optional. Link names may contain letters,
+numbers and spaces, but are *not* case sensitive:
+
+    I start my morning with a cup of coffee and
+    [The New York Times][NY Times].
+
+    [ny times]: http://www.nytimes.com/
+
+Output:
+
+    <p>I start my morning with a cup of coffee and
+    <a href="http://www.nytimes.com/">The New York Times</a>.</p>
+
+
+### Images ###
+
+Image syntax is very much like link syntax.
+
+Inline (titles are optional):
+
+    ![alt text](/path/to/img.jpg "Title")
+
+Reference-style:
+
+    ![alt text][id]
+
+    [id]: /path/to/img.jpg "Title"
+
+Both of the above examples produce the same output:
+
+    <img src="/path/to/img.jpg" alt="alt text" title="Title" />
+
+
+
+### Code ###
+
+In a regular paragraph, you can create code span by wrapping text in
+backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
+`>`) will automatically be translated into HTML entities. This makes
+it easy to use Markdown to write about HTML example code:
+
+    I strongly recommend against using any `<blink>` tags.
+
+    I wish SmartyPants used named entities like `&mdash;`
+    instead of decimal-encoded entites like `&#8212;`.
+
+Output:
+
+    <p>I strongly recommend against using any
+    <code>&lt;blink&gt;</code> tags.</p>
+    
+    <p>I wish SmartyPants used named entities like
+    <code>&amp;mdash;</code> instead of decimal-encoded
+    entites like <code>&amp;#8212;</code>.</p>
+
+
+To specify an entire block of pre-formatted code, indent every line of
+the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
+and `>` characters will be escaped automatically.
+
+Markdown:
+
+    If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:
+
+        <blockquote>
+            <p>For example.</p>
+        </blockquote>
+
+Output:
+
+    <p>If you want your page to validate under XHTML 1.0 Strict,
+    you've got to put paragraph tags in your blockquotes:</p>
+    
+    <pre><code>&lt;blockquote&gt;
+        &lt;p&gt;For example.&lt;/p&gt;
+    &lt;/blockquote&gt;
+    </code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.html b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.html
new file mode 100644
index 0000000..61dde59
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.html	
@@ -0,0 +1,946 @@
+<h1>Markdown: Syntax</h1>
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+    <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+<ul>
+<li><a href="#overview">Overview</a>
+
+<ul>
+<li><a href="#philosophy">Philosophy</a></li>
+<li><a href="#html">Inline HTML</a></li>
+<li><a href="#autoescape">Automatic Escaping for Special Characters</a></li>
+</ul></li>
+<li><a href="#block">Block Elements</a>
+
+<ul>
+<li><a href="#p">Paragraphs and Line Breaks</a></li>
+<li><a href="#header">Headers</a></li>
+<li><a href="#blockquote">Blockquotes</a></li>
+<li><a href="#list">Lists</a></li>
+<li><a href="#precode">Code Blocks</a></li>
+<li><a href="#hr">Horizontal Rules</a></li>
+</ul></li>
+<li><a href="#span">Span Elements</a>
+
+<ul>
+<li><a href="#link">Links</a></li>
+<li><a href="#em">Emphasis</a></li>
+<li><a href="#code">Code</a></li>
+<li><a href="#img">Images</a></li>
+</ul></li>
+<li><a href="#misc">Miscellaneous</a>
+
+<ul>
+<li><a href="#backslash">Backslash Escapes</a></li>
+<li><a href="#autolink">Automatic Links</a></li>
+</ul></li>
+</ul>
+
+<p><strong>Note:</strong> This document is itself written using Markdown; you
+can <a href="/projects/markdown/syntax.text">see the source for it by adding '.text' to the URL</a>.</p>
+
+<hr>
+
+<h2 id="overview">Overview</h2>
+
+<h3 id="philosophy">Philosophy</h3>
+
+<p>Markdown is intended to be as easy-to-read and easy-to-write as is feasible.</p>
+
+<p>Readability, however, is emphasized above all else. A Markdown-formatted
+document should be publishable as-is, as plain text, without looking
+like it's been marked up with tags or formatting instructions. While
+Markdown's syntax has been influenced by several existing text-to-HTML
+filters -- including <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a>, <a href="http://www.aaronsw.com/2002/atx/">atx</a>, <a href="http://textism.com/tools/textile/">Textile</a>, <a href="http://docutils.sourceforge.net/rst.html">reStructuredText</a>,
+<a href="http://www.triptico.com/software/grutatxt.html">Grutatext</a>, and <a href="http://ettext.taint.org/doc/">EtText</a> -- the single biggest source of
+inspiration for Markdown's syntax is the format of plain text email.</p>
+
+<p>To this end, Markdown's syntax is comprised entirely of punctuation
+characters, which punctuation characters have been carefully chosen so
+as to look like what they mean. E.g., asterisks around a word actually
+look like *emphasis*. Markdown lists look like, well, lists. Even
+blockquotes look like quoted passages of text, assuming you've ever
+used email.</p>
+
+<h3 id="html">Inline HTML</h3>
+
+<p>Markdown's syntax is intended for one purpose: to be used as a
+format for <em>writing</em> for the web.</p>
+
+<p>Markdown is not a replacement for HTML, or even close to it. Its
+syntax is very small, corresponding only to a very small subset of
+HTML tags. The idea is <em>not</em> to create a syntax that makes it easier
+to insert HTML tags. In my opinion, HTML tags are already easy to
+insert. The idea for Markdown is to make it easy to read, write, and
+edit prose. HTML is a <em>publishing</em> format; Markdown is a <em>writing</em>
+format. Thus, Markdown's formatting syntax only addresses issues that
+can be conveyed in plain text.</p>
+
+<p>For any markup that is not covered by Markdown's syntax, you simply
+use HTML itself. There's no need to preface it or delimit it to
+indicate that you're switching from Markdown to HTML; you just use
+the tags.</p>
+
+<p>The only restrictions are that block-level HTML elements -- e.g. <code>&lt;div&gt;</code>,
+<code>&lt;table&gt;</code>, <code>&lt;pre&gt;</code>, <code>&lt;p&gt;</code>, etc. -- must be separated from surrounding
+content by blank lines, and the start and end tags of the block should
+not be indented with tabs or spaces. Markdown is smart enough not
+to add extra (unwanted) <code>&lt;p&gt;</code> tags around HTML block-level tags.</p>
+
+<p>For example, to add an HTML table to a Markdown article:</p>
+
+<pre><code>This is a regular paragraph.
+
+&lt;table&gt;
+    &lt;tr&gt;
+        &lt;td&gt;Foo&lt;/td&gt;
+    &lt;/tr&gt;
+&lt;/table&gt;
+
+This is another regular paragraph.
+</code></pre>
+
+<p>Note that Markdown formatting syntax is not processed within block-level
+HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an
+HTML block.</p>
+
+<p>Span-level HTML tags -- e.g. <code>&lt;span&gt;</code>, <code>&lt;cite&gt;</code>, or <code>&lt;del&gt;</code> -- can be
+used anywhere in a Markdown paragraph, list item, or header. If you
+want, you can even use HTML tags instead of Markdown formatting; e.g. if
+you'd prefer to use HTML <code>&lt;a&gt;</code> or <code>&lt;img&gt;</code> tags instead of Markdown's
+link or image syntax, go right ahead.</p>
+
+<p>Unlike block-level HTML tags, Markdown syntax <em>is</em> processed within
+span-level tags.</p>
+
+<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
+
+<p>In HTML, there are two characters that demand special treatment: <code>&lt;</code>
+and <code>&amp;</code>. Left angle brackets are used to start tags; ampersands are
+used to denote HTML entities. If you want to use them as literal
+characters, you must escape them as entities, e.g. <code>&amp;lt;</code>, and
+<code>&amp;amp;</code>.</p>
+
+<p>Ampersands in particular are bedeviling for web writers. If you want to
+write about 'AT&amp;T', you need to write '<code>AT&amp;amp;T</code>'. You even need to
+escape ampersands within URLs. Thus, if you want to link to:</p>
+
+<pre><code>http://images.google.com/images?num=30&amp;q=larry+bird
+</code></pre>
+
+<p>you need to encode the URL as:</p>
+
+<pre><code>http://images.google.com/images?num=30&amp;amp;q=larry+bird
+</code></pre>
+
+<p>in your anchor tag <code>href</code> attribute. Needless to say, this is easy to
+forget, and is probably the single most common source of HTML validation
+errors in otherwise well-marked-up web sites.</p>
+
+<p>Markdown allows you to use these characters naturally, taking care of
+all the necessary escaping for you. If you use an ampersand as part of
+an HTML entity, it remains unchanged; otherwise it will be translated
+into <code>&amp;amp;</code>.</p>
+
+<p>So, if you want to include a copyright symbol in your article, you can write:</p>
+
+<pre><code>&amp;copy;
+</code></pre>
+
+<p>and Markdown will leave it alone. But if you write:</p>
+
+<pre><code>AT&amp;T
+</code></pre>
+
+<p>Markdown will translate it to:</p>
+
+<pre><code>AT&amp;amp;T
+</code></pre>
+
+<p>Similarly, because Markdown supports <a href="#html">inline HTML</a>, if you use
+angle brackets as delimiters for HTML tags, Markdown will treat them as
+such. But if you write:</p>
+
+<pre><code>4 &lt; 5
+</code></pre>
+
+<p>Markdown will translate it to:</p>
+
+<pre><code>4 &amp;lt; 5
+</code></pre>
+
+<p>However, inside Markdown code spans and blocks, angle brackets and
+ampersands are <em>always</em> encoded automatically. This makes it easy to use
+Markdown to write about HTML code. (As opposed to raw HTML, which is a
+terrible format for writing about HTML syntax, because every single <code>&lt;</code>
+and <code>&amp;</code> in your example code needs to be escaped.)</p>
+
+<hr>
+
+<h2 id="block">Block Elements</h2>
+
+<h3 id="p">Paragraphs and Line Breaks</h3>
+
+<p>A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing but spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.</p>
+
+<p>The implication of the &quot;one or more consecutive lines of text&quot; rule is
+that Markdown supports &quot;hard-wrapped&quot; text paragraphs. This differs
+significantly from most other text-to-HTML formatters (including Movable
+Type's &quot;Convert Line Breaks&quot; option) which translate every line break
+character in a paragraph into a <code>&lt;br /&gt;</code> tag.</p>
+
+<p>When you <em>do</em> want to insert a <code>&lt;br /&gt;</code> break tag using Markdown, you
+end a line with two or more spaces, then type return.</p>
+
+<p>Yes, this takes a tad more effort to create a <code>&lt;br /&gt;</code>, but a simplistic
+&quot;every line break is a <code>&lt;br /&gt;</code>&quot; rule wouldn't work for Markdown.
+Markdown's email-style <a href="#blockquote">blockquoting</a> and multi-paragraph <a href="#list">list items</a>
+work best -- and look better -- when you format them with hard breaks.</p>
+
+<h3 id="header">Headers</h3>
+
+<p>Markdown supports two styles of headers, <a href="http://docutils.sourceforge.net/mirror/setext.html">Setext</a> and <a href="http://www.aaronsw.com/2002/atx/">atx</a>.</p>
+
+<p>Setext-style headers are &quot;underlined&quot; using equal signs (for first-level
+headers) and dashes (for second-level headers). For example:</p>
+
+<pre><code>This is an H1
+=============
+
+This is an H2
+-------------
+</code></pre>
+
+<p>Any number of underlining <code>=</code>'s or <code>-</code>'s will work.</p>
+
+<p>Atx-style headers use 1-6 hash characters at the start of the line,
+corresponding to header levels 1-6. For example:</p>
+
+<pre><code># This is an H1
+
+## This is an H2
+
+###### This is an H6
+</code></pre>
+
+<p>Optionally, you may &quot;close&quot; atx-style headers. This is purely
+cosmetic -- you can use this if you think it looks better. The
+closing hashes don't even need to match the number of hashes
+used to open the header. (The number of opening hashes
+determines the header level.) :</p>
+
+<pre><code># This is an H1 #
+
+## This is an H2 ##
+
+### This is an H3 ######
+</code></pre>
+
+<h3 id="blockquote">Blockquotes</h3>
+
+<p>Markdown uses email-style <code>&gt;</code> characters for blockquoting. If you're
+familiar with quoting passages of text in an email message, then you
+know how to create a blockquote in Markdown. It looks best if you hard
+wrap the text and put a <code>&gt;</code> before every line:</p>
+
+<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+&gt; consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+&gt; Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+&gt; 
+&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+&gt; id sem consectetuer libero luctus adipiscing.
+</code></pre>
+
+<p>Markdown allows you to be lazy and only put the <code>&gt;</code> before the first
+line of a hard-wrapped paragraph:</p>
+
+<pre><code>&gt; This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+&gt; Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+id sem consectetuer libero luctus adipiscing.
+</code></pre>
+
+<p>Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
+adding additional levels of <code>&gt;</code>:</p>
+
+<pre><code>&gt; This is the first level of quoting.
+&gt;
+&gt; &gt; This is nested blockquote.
+&gt;
+&gt; Back to the first level.
+</code></pre>
+
+<p>Blockquotes can contain other Markdown elements, including headers, lists,
+and code blocks:</p>
+
+<pre><code>&gt; ## This is a header.
+&gt; 
+&gt; 1.   This is the first list item.
+&gt; 2.   This is the second list item.
+&gt; 
+&gt; Here's some example code:
+&gt; 
+&gt;     return shell_exec(&quot;echo $input | $markdown_script&quot;);
+</code></pre>
+
+<p>Any decent text editor should make email-style quoting easy. For
+example, with BBEdit, you can make a selection and choose Increase
+Quote Level from the Text menu.</p>
+
+<h3 id="list">Lists</h3>
+
+<p>Markdown supports ordered (numbered) and unordered (bulleted) lists.</p>
+
+<p>Unordered lists use asterisks, pluses, and hyphens -- interchangably
+-- as list markers:</p>
+
+<pre><code>*   Red
+*   Green
+*   Blue
+</code></pre>
+
+<p>is equivalent to:</p>
+
+<pre><code>+   Red
++   Green
++   Blue
+</code></pre>
+
+<p>and:</p>
+
+<pre><code>-   Red
+-   Green
+-   Blue
+</code></pre>
+
+<p>Ordered lists use numbers followed by periods:</p>
+
+<pre><code>1.  Bird
+2.  McHale
+3.  Parish
+</code></pre>
+
+<p>It's important to note that the actual numbers you use to mark the
+list have no effect on the HTML output Markdown produces. The HTML
+Markdown produces from the above list is:</p>
+
+<pre><code>&lt;ol&gt;
+&lt;li&gt;Bird&lt;/li&gt;
+&lt;li&gt;McHale&lt;/li&gt;
+&lt;li&gt;Parish&lt;/li&gt;
+&lt;/ol&gt;
+</code></pre>
+
+<p>If you instead wrote the list in Markdown like this:</p>
+
+<pre><code>1.  Bird
+1.  McHale
+1.  Parish
+</code></pre>
+
+<p>or even:</p>
+
+<pre><code>3. Bird
+1. McHale
+8. Parish
+</code></pre>
+
+<p>you'd get the exact same HTML output. The point is, if you want to,
+you can use ordinal numbers in your ordered Markdown lists, so that
+the numbers in your source match the numbers in your published HTML.
+But if you want to be lazy, you don't have to.</p>
+
+<p>If you do use lazy list numbering, however, you should still start the
+list with the number 1. At some point in the future, Markdown may support
+starting ordered lists at an arbitrary number.</p>
+
+<p>List markers typically start at the left margin, but may be indented by
+up to three spaces. List markers must be followed by one or more spaces
+or a tab.</p>
+
+<p>To make lists look nice, you can wrap items with hanging indents:</p>
+
+<pre><code>*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+</code></pre>
+
+<p>But if you want to be lazy, you don't have to:</p>
+
+<pre><code>*   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+viverra nec, fringilla in, laoreet vitae, risus.
+*   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+Suspendisse id sem consectetuer libero luctus adipiscing.
+</code></pre>
+
+<p>If list items are separated by blank lines, Markdown will wrap the
+items in <code>&lt;p&gt;</code> tags in the HTML output. For example, this input:</p>
+
+<pre><code>*   Bird
+*   Magic
+</code></pre>
+
+<p>will turn into:</p>
+
+<pre><code>&lt;ul&gt;
+&lt;li&gt;Bird&lt;/li&gt;
+&lt;li&gt;Magic&lt;/li&gt;
+&lt;/ul&gt;
+</code></pre>
+
+<p>But this:</p>
+
+<pre><code>*   Bird
+
+*   Magic
+</code></pre>
+
+<p>will turn into:</p>
+
+<pre><code>&lt;ul&gt;
+&lt;li&gt;&lt;p&gt;Bird&lt;/p&gt;&lt;/li&gt;
+&lt;li&gt;&lt;p&gt;Magic&lt;/p&gt;&lt;/li&gt;
+&lt;/ul&gt;
+</code></pre>
+
+<p>List items may consist of multiple paragraphs. Each subsequent
+paragraph in a list item must be intended by either 4 spaces
+or one tab:</p>
+
+<pre><code>1.  This is a list item with two paragraphs. Lorem ipsum dolor
+    sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+    mi posuere lectus.
+
+    Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+    vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+    sit amet velit.
+
+2.  Suspendisse id sem consectetuer libero luctus adipiscing.
+</code></pre>
+
+<p>It looks nice if you indent every line of the subsequent
+paragraphs, but here again, Markdown will allow you to be
+lazy:</p>
+
+<pre><code>*   This is a list item with two paragraphs.
+
+    This is the second paragraph in the list item. You're
+only required to indent the first line. Lorem ipsum dolor
+sit amet, consectetuer adipiscing elit.
+
+*   Another item in the same list.
+</code></pre>
+
+<p>To put a blockquote within a list item, the blockquote's <code>&gt;</code>
+delimiters need to be indented:</p>
+
+<pre><code>*   A list item with a blockquote:
+
+    &gt; This is a blockquote
+    &gt; inside a list item.
+</code></pre>
+
+<p>To put a code block within a list item, the code block needs
+to be indented <em>twice</em> -- 8 spaces or two tabs:</p>
+
+<pre><code>*   A list item with a code block:
+
+        &lt;code goes here&gt;
+</code></pre>
+
+<p>It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:</p>
+
+<pre><code>1986. What a great season.
+</code></pre>
+
+<p>In other words, a <em>number-period-space</em> sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:</p>
+
+<pre><code>1986\. What a great season.
+</code></pre>
+
+<h3 id="precode">Code Blocks</h3>
+
+<p>Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both <code>&lt;pre&gt;</code> and <code>&lt;code&gt;</code> tags.</p>
+
+<p>To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:</p>
+
+<pre><code>This is a normal paragraph:
+
+    This is a code block.
+</code></pre>
+
+<p>Markdown will generate:</p>
+
+<pre><code>&lt;p&gt;This is a normal paragraph:&lt;/p&gt;
+
+&lt;pre&gt;&lt;code&gt;This is a code block.
+&lt;/code&gt;&lt;/pre&gt;
+</code></pre>
+
+<p>One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:</p>
+
+<pre><code>Here is an example of AppleScript:
+
+    tell application &quot;Foo&quot;
+        beep
+    end tell
+</code></pre>
+
+<p>will turn into:</p>
+
+<pre><code>&lt;p&gt;Here is an example of AppleScript:&lt;/p&gt;
+
+&lt;pre&gt;&lt;code&gt;tell application &quot;Foo&quot;
+    beep
+end tell
+&lt;/code&gt;&lt;/pre&gt;
+</code></pre>
+
+<p>A code block continues until it reaches a line that is not indented
+(or the end of the article).</p>
+
+<p>Within a code block, ampersands (<code>&amp;</code>) and angle brackets (<code>&lt;</code> and <code>&gt;</code>)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:</p>
+
+<pre><code>    &lt;div class=&quot;footer&quot;&gt;
+        &amp;copy; 2004 Foo Corporation
+    &lt;/div&gt;
+</code></pre>
+
+<p>will turn into:</p>
+
+<pre><code>&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;footer&quot;&amp;gt;
+    &amp;amp;copy; 2004 Foo Corporation
+&amp;lt;/div&amp;gt;
+&lt;/code&gt;&lt;/pre&gt;
+</code></pre>
+
+<p>Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.</p>
+
+<h3 id="hr">Horizontal Rules</h3>
+
+<p>You can produce a horizontal rule tag (<code>&lt;hr /&gt;</code>) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:</p>
+
+<pre><code>* * *
+
+***
+
+*****
+
+- - -
+
+---------------------------------------
+
+_ _ _
+</code></pre>
+
+<hr>
+
+<h2 id="span">Span Elements</h2>
+
+<h3 id="link">Links</h3>
+
+<p>Markdown supports two style of links: <em>inline</em> and <em>reference</em>.</p>
+
+<p>In both styles, the link text is delimited by [square brackets].</p>
+
+<p>To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an <em>optional</em>
+title for the link, surrounded in quotes. For example:</p>
+
+<pre><code>This is [an example](http://example.com/ &quot;Title&quot;) inline link.
+
+[This link](http://example.net/) has no title attribute.
+</code></pre>
+
+<p>Will produce:</p>
+
+<pre><code>&lt;p&gt;This is &lt;a href=&quot;http://example.com/&quot; title=&quot;Title&quot;&gt;
+an example&lt;/a&gt; inline link.&lt;/p&gt;
+
+&lt;p&gt;&lt;a href=&quot;http://example.net/&quot;&gt;This link&lt;/a&gt; has no
+title attribute.&lt;/p&gt;
+</code></pre>
+
+<p>If you're referring to a local resource on the same server, you can
+use relative paths:</p>
+
+<pre><code>See my [About](/about/) page for details.
+</code></pre>
+
+<p>Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:</p>
+
+<pre><code>This is [an example][id] reference-style link.
+</code></pre>
+
+<p>You can optionally use a space to separate the sets of brackets:</p>
+
+<pre><code>This is [an example] [id] reference-style link.
+</code></pre>
+
+<p>Then, anywhere in the document, you define your link label like this,
+on a line by itself:</p>
+
+<pre><code>[id]: http://example.com/  &quot;Optional Title Here&quot;
+</code></pre>
+
+<p>That is:</p>
+
+<ul>
+<li>Square brackets containing the link identifier (optionally
+indented from the left margin using up to three spaces);</li>
+<li>followed by a colon;</li>
+<li>followed by one or more spaces (or tabs);</li>
+<li>followed by the URL for the link;</li>
+<li>optionally followed by a title attribute for the link, enclosed
+in double or single quotes.</li>
+</ul>
+
+<p>The link URL may, optionally, be surrounded by angle brackets:</p>
+
+<pre><code>[id]: &lt;http://example.com/&gt;  &quot;Optional Title Here&quot;
+</code></pre>
+
+<p>You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:</p>
+
+<pre><code>[id]: http://example.com/longish/path/to/resource/here
+    &quot;Optional Title Here&quot;
+</code></pre>
+
+<p>Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.</p>
+
+<p>Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are <em>not</em> case sensitive. E.g. these two links:</p>
+
+<pre><code>[link text][a]
+[link text][A]
+</code></pre>
+
+<p>are equivalent.</p>
+
+<p>The <em>implicit link name</em> shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+&quot;Google&quot; to the google.com web site, you could simply write:</p>
+
+<pre><code>[Google][]
+</code></pre>
+
+<p>And then define the link:</p>
+
+<pre><code>[Google]: http://google.com/
+</code></pre>
+
+<p>Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:</p>
+
+<pre><code>Visit [Daring Fireball][] for more information.
+</code></pre>
+
+<p>And then define the link:</p>
+
+<pre><code>[Daring Fireball]: http://daringfireball.net/
+</code></pre>
+
+<p>Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.</p>
+
+<p>Here's an example of reference links in action:</p>
+
+<pre><code>I get 10 times more traffic from [Google] [1] than from
+[Yahoo] [2] or [MSN] [3].
+
+  [1]: http://google.com/        &quot;Google&quot;
+  [2]: http://search.yahoo.com/  &quot;Yahoo Search&quot;
+  [3]: http://search.msn.com/    &quot;MSN Search&quot;
+</code></pre>
+
+<p>Using the implicit link name shortcut, you could instead write:</p>
+
+<pre><code>I get 10 times more traffic from [Google][] than from
+[Yahoo][] or [MSN][].
+
+  [google]: http://google.com/        &quot;Google&quot;
+  [yahoo]:  http://search.yahoo.com/  &quot;Yahoo Search&quot;
+  [msn]:    http://search.msn.com/    &quot;MSN Search&quot;
+</code></pre>
+
+<p>Both of the above examples will produce the following HTML output:</p>
+
+<pre><code>&lt;p&gt;I get 10 times more traffic from &lt;a href=&quot;http://google.com/&quot;
+title=&quot;Google&quot;&gt;Google&lt;/a&gt; than from
+&lt;a href=&quot;http://search.yahoo.com/&quot; title=&quot;Yahoo Search&quot;&gt;Yahoo&lt;/a&gt;
+or &lt;a href=&quot;http://search.msn.com/&quot; title=&quot;MSN Search&quot;&gt;MSN&lt;/a&gt;.&lt;/p&gt;
+</code></pre>
+
+<p>For comparison, here is the same paragraph written using
+Markdown's inline link style:</p>
+
+<pre><code>I get 10 times more traffic from [Google](http://google.com/ &quot;Google&quot;)
+than from [Yahoo](http://search.yahoo.com/ &quot;Yahoo Search&quot;) or
+[MSN](http://search.msn.com/ &quot;MSN Search&quot;).
+</code></pre>
+
+<p>The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.</p>
+
+<p>With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.</p>
+
+<h3 id="em">Emphasis</h3>
+
+<p>Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of
+emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an
+HTML <code>&lt;em&gt;</code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML
+<code>&lt;strong&gt;</code> tag. E.g., this input:</p>
+
+<pre><code>*single asterisks*
+
+_single underscores_
+
+**double asterisks**
+
+__double underscores__
+</code></pre>
+
+<p>will produce:</p>
+
+<pre><code>&lt;em&gt;single asterisks&lt;/em&gt;
+
+&lt;em&gt;single underscores&lt;/em&gt;
+
+&lt;strong&gt;double asterisks&lt;/strong&gt;
+
+&lt;strong&gt;double underscores&lt;/strong&gt;
+</code></pre>
+
+<p>You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.</p>
+
+<p>Emphasis can be used in the middle of a word:</p>
+
+<pre><code>un*fucking*believable
+</code></pre>
+
+<p>But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a
+literal asterisk or underscore.</p>
+
+<p>To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:</p>
+
+<pre><code>\*this text is surrounded by literal asterisks\*
+</code></pre>
+
+<h3 id="code">Code</h3>
+
+<p>To indicate a span of code, wrap it with backtick quotes (<code>`</code>).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:</p>
+
+<pre><code>Use the `printf()` function.
+</code></pre>
+
+<p>will produce:</p>
+
+<pre><code>&lt;p&gt;Use the &lt;code&gt;printf()&lt;/code&gt; function.&lt;/p&gt;
+</code></pre>
+
+<p>To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:</p>
+
+<pre><code>``There is a literal backtick (`) here.``
+</code></pre>
+
+<p>which will produce this:</p>
+
+<pre><code>&lt;p&gt;&lt;code&gt;There is a literal backtick (`) here.&lt;/code&gt;&lt;/p&gt;
+</code></pre>
+
+<p>The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:</p>
+
+<pre><code>A single backtick in a code span: `` ` ``
+
+A backtick-delimited string in a code span: `` `foo` ``
+</code></pre>
+
+<p>will produce:</p>
+
+<pre><code>&lt;p&gt;A single backtick in a code span: &lt;code&gt;`&lt;/code&gt;&lt;/p&gt;
+
+&lt;p&gt;A backtick-delimited string in a code span: &lt;code&gt;`foo`&lt;/code&gt;&lt;/p&gt;
+</code></pre>
+
+<p>With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:</p>
+
+<pre><code>Please don't use any `&lt;blink&gt;` tags.
+</code></pre>
+
+<p>into:</p>
+
+<pre><code>&lt;p&gt;Please don't use any &lt;code&gt;&amp;lt;blink&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;
+</code></pre>
+
+<p>You can write this:</p>
+
+<pre><code>`&amp;#8212;` is the decimal-encoded equivalent of `&amp;mdash;`.
+</code></pre>
+
+<p>to produce:</p>
+
+<pre><code>&lt;p&gt;&lt;code&gt;&amp;amp;#8212;&lt;/code&gt; is the decimal-encoded
+equivalent of &lt;code&gt;&amp;amp;mdash;&lt;/code&gt;.&lt;/p&gt;
+</code></pre>
+
+<h3 id="img">Images</h3>
+
+<p>Admittedly, it's fairly difficult to devise a &quot;natural&quot; syntax for
+placing images into a plain text document format.</p>
+
+<p>Markdown uses an image syntax that is intended to resemble the syntax
+for links, allowing for two styles: <em>inline</em> and <em>reference</em>.</p>
+
+<p>Inline image syntax looks like this:</p>
+
+<pre><code>![Alt text](/path/to/img.jpg)
+
+![Alt text](/path/to/img.jpg &quot;Optional title&quot;)
+</code></pre>
+
+<p>That is:</p>
+
+<ul>
+<li>An exclamation mark: <code>!</code>;</li>
+<li>followed by a set of square brackets, containing the <code>alt</code>
+attribute text for the image;</li>
+<li>followed by a set of parentheses, containing the URL or path to
+the image, and an optional <code>title</code> attribute enclosed in double
+or single quotes.</li>
+</ul>
+
+<p>Reference-style image syntax looks like this:</p>
+
+<pre><code>![Alt text][id]
+</code></pre>
+
+<p>Where &quot;id&quot; is the name of a defined image reference. Image references
+are defined using syntax identical to link references:</p>
+
+<pre><code>[id]: url/to/image  &quot;Optional title attribute&quot;
+</code></pre>
+
+<p>As of this writing, Markdown has no syntax for specifying the
+dimensions of an image; if this is important to you, you can simply
+use regular HTML <code>&lt;img&gt;</code> tags.</p>
+
+<hr>
+
+<h2 id="misc">Miscellaneous</h2>
+
+<h3 id="autolink">Automatic Links</h3>
+
+<p>Markdown supports a shortcut style for creating &quot;automatic&quot; links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:</p>
+
+<pre><code>&lt;http://example.com/&gt;
+</code></pre>
+
+<p>Markdown will turn this into:</p>
+
+<pre><code>&lt;a href=&quot;http://example.com/&quot;&gt;http://example.com/&lt;/a&gt;
+</code></pre>
+
+<p>Automatic links for email addresses work similarly, except that
+Markdown will also perform a bit of randomized decimal and hex
+entity-encoding to help obscure your address from address-harvesting
+spambots. For example, Markdown will turn this:</p>
+
+<pre><code>&lt;address@example.com&gt;
+</code></pre>
+
+<p>into something like this:</p>
+
+<pre><code>&lt;a href=&quot;&amp;#x6D;&amp;#x61;i&amp;#x6C;&amp;#x74;&amp;#x6F;:&amp;#x61;&amp;#x64;&amp;#x64;&amp;#x72;&amp;#x65;
+&amp;#115;&amp;#115;&amp;#64;&amp;#101;&amp;#120;&amp;#x61;&amp;#109;&amp;#x70;&amp;#x6C;e&amp;#x2E;&amp;#99;&amp;#111;
+&amp;#109;&quot;&gt;&amp;#x61;&amp;#x64;&amp;#x64;&amp;#x72;&amp;#x65;&amp;#115;&amp;#115;&amp;#64;&amp;#101;&amp;#120;&amp;#x61;
+&amp;#109;&amp;#x70;&amp;#x6C;e&amp;#x2E;&amp;#99;&amp;#111;&amp;#109;&lt;/a&gt;
+</code></pre>
+
+<p>which will render in a browser as a clickable link to &quot;address@example.com&quot;.</p>
+
+<p>(This sort of entity-encoding trick will indeed fool many, if not
+most, address-harvesting bots, but it definitely won't fool all of
+them. It's better than nothing, but an address published in this way
+will probably eventually start receiving spam.)</p>
+
+<h3 id="backslash">Backslash Escapes</h3>
+
+<p>Markdown allows you to use backslash escapes to generate literal
+characters which would otherwise have special meaning in Markdown's
+formatting syntax. For example, if you wanted to surround a word with
+literal asterisks (instead of an HTML <code>&lt;em&gt;</code> tag), you can backslashes
+before the asterisks, like this:</p>
+
+<pre><code>\*literal asterisks\*
+</code></pre>
+
+<p>Markdown provides backslash escapes for the following characters:</p>
+
+<pre><code>\   backslash
+`   backtick
+*   asterisk
+_   underscore
+{}  curly braces
+[]  square brackets
+()  parentheses
+#   hash mark
++   plus sign
+-   minus sign (hyphen)
+.   dot
+!   exclamation mark
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.text b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.text
new file mode 100644
index 0000000..57360a1
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Markdown Documentation - Syntax.text	
@@ -0,0 +1,888 @@
+Markdown: Syntax
+================
+
+<ul id="ProjectSubmenu">
+    <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+    <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+    <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+    <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+    <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+*   [Overview](#overview)
+    *   [Philosophy](#philosophy)
+    *   [Inline HTML](#html)
+    *   [Automatic Escaping for Special Characters](#autoescape)
+*   [Block Elements](#block)
+    *   [Paragraphs and Line Breaks](#p)
+    *   [Headers](#header)
+    *   [Blockquotes](#blockquote)
+    *   [Lists](#list)
+    *   [Code Blocks](#precode)
+    *   [Horizontal Rules](#hr)
+*   [Span Elements](#span)
+    *   [Links](#link)
+    *   [Emphasis](#em)
+    *   [Code](#code)
+    *   [Images](#img)
+*   [Miscellaneous](#misc)
+    *   [Backslash Escapes](#backslash)
+    *   [Automatic Links](#autolink)
+
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL][src].
+
+  [src]: /projects/markdown/syntax.text
+
+* * *
+
+<h2 id="overview">Overview</h2>
+
+<h3 id="philosophy">Philosophy</h3>
+
+Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
+
+Readability, however, is emphasized above all else. A Markdown-formatted
+document should be publishable as-is, as plain text, without looking
+like it's been marked up with tags or formatting instructions. While
+Markdown's syntax has been influenced by several existing text-to-HTML
+filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
+[Grutatext] [5], and [EtText] [6] -- the single biggest source of
+inspiration for Markdown's syntax is the format of plain text email.
+
+  [1]: http://docutils.sourceforge.net/mirror/setext.html
+  [2]: http://www.aaronsw.com/2002/atx/
+  [3]: http://textism.com/tools/textile/
+  [4]: http://docutils.sourceforge.net/rst.html
+  [5]: http://www.triptico.com/software/grutatxt.html
+  [6]: http://ettext.taint.org/doc/
+
+To this end, Markdown's syntax is comprised entirely of punctuation
+characters, which punctuation characters have been carefully chosen so
+as to look like what they mean. E.g., asterisks around a word actually
+look like \*emphasis\*. Markdown lists look like, well, lists. Even
+blockquotes look like quoted passages of text, assuming you've ever
+used email.
+
+
+
+<h3 id="html">Inline HTML</h3>
+
+Markdown's syntax is intended for one purpose: to be used as a
+format for *writing* for the web.
+
+Markdown is not a replacement for HTML, or even close to it. Its
+syntax is very small, corresponding only to a very small subset of
+HTML tags. The idea is *not* to create a syntax that makes it easier
+to insert HTML tags. In my opinion, HTML tags are already easy to
+insert. The idea for Markdown is to make it easy to read, write, and
+edit prose. HTML is a *publishing* format; Markdown is a *writing*
+format. Thus, Markdown's formatting syntax only addresses issues that
+can be conveyed in plain text.
+
+For any markup that is not covered by Markdown's syntax, you simply
+use HTML itself. There's no need to preface it or delimit it to
+indicate that you're switching from Markdown to HTML; you just use
+the tags.
+
+The only restrictions are that block-level HTML elements -- e.g. `<div>`,
+`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
+content by blank lines, and the start and end tags of the block should
+not be indented with tabs or spaces. Markdown is smart enough not
+to add extra (unwanted) `<p>` tags around HTML block-level tags.
+
+For example, to add an HTML table to a Markdown article:
+
+    This is a regular paragraph.
+
+    <table>
+        <tr>
+            <td>Foo</td>
+        </tr>
+    </table>
+
+    This is another regular paragraph.
+
+Note that Markdown formatting syntax is not processed within block-level
+HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
+HTML block.
+
+Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
+used anywhere in a Markdown paragraph, list item, or header. If you
+want, you can even use HTML tags instead of Markdown formatting; e.g. if
+you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
+link or image syntax, go right ahead.
+
+Unlike block-level HTML tags, Markdown syntax *is* processed within
+span-level tags.
+
+
+<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
+
+In HTML, there are two characters that demand special treatment: `<`
+and `&`. Left angle brackets are used to start tags; ampersands are
+used to denote HTML entities. If you want to use them as literal
+characters, you must escape them as entities, e.g. `&lt;`, and
+`&amp;`.
+
+Ampersands in particular are bedeviling for web writers. If you want to
+write about 'AT&T', you need to write '`AT&amp;T`'. You even need to
+escape ampersands within URLs. Thus, if you want to link to:
+
+    http://images.google.com/images?num=30&q=larry+bird
+
+you need to encode the URL as:
+
+    http://images.google.com/images?num=30&amp;q=larry+bird
+
+in your anchor tag `href` attribute. Needless to say, this is easy to
+forget, and is probably the single most common source of HTML validation
+errors in otherwise well-marked-up web sites.
+
+Markdown allows you to use these characters naturally, taking care of
+all the necessary escaping for you. If you use an ampersand as part of
+an HTML entity, it remains unchanged; otherwise it will be translated
+into `&amp;`.
+
+So, if you want to include a copyright symbol in your article, you can write:
+
+    &copy;
+
+and Markdown will leave it alone. But if you write:
+
+    AT&T
+
+Markdown will translate it to:
+
+    AT&amp;T
+
+Similarly, because Markdown supports [inline HTML](#html), if you use
+angle brackets as delimiters for HTML tags, Markdown will treat them as
+such. But if you write:
+
+    4 < 5
+
+Markdown will translate it to:
+
+    4 &lt; 5
+
+However, inside Markdown code spans and blocks, angle brackets and
+ampersands are *always* encoded automatically. This makes it easy to use
+Markdown to write about HTML code. (As opposed to raw HTML, which is a
+terrible format for writing about HTML syntax, because every single `<`
+and `&` in your example code needs to be escaped.)
+
+
+* * *
+
+
+<h2 id="block">Block Elements</h2>
+
+
+<h3 id="p">Paragraphs and Line Breaks</h3>
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing but spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+The implication of the "one or more consecutive lines of text" rule is
+that Markdown supports "hard-wrapped" text paragraphs. This differs
+significantly from most other text-to-HTML formatters (including Movable
+Type's "Convert Line Breaks" option) which translate every line break
+character in a paragraph into a `<br />` tag.
+
+When you *do* want to insert a `<br />` break tag using Markdown, you
+end a line with two or more spaces, then type return.
+
+Yes, this takes a tad more effort to create a `<br />`, but a simplistic
+"every line break is a `<br />`" rule wouldn't work for Markdown.
+Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
+work best -- and look better -- when you format them with hard breaks.
+
+  [bq]: #blockquote
+  [l]:  #list
+
+
+
+<h3 id="header">Headers</h3>
+
+Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
+
+Setext-style headers are "underlined" using equal signs (for first-level
+headers) and dashes (for second-level headers). For example:
+
+    This is an H1
+    =============
+
+    This is an H2
+    -------------
+
+Any number of underlining `=`'s or `-`'s will work.
+
+Atx-style headers use 1-6 hash characters at the start of the line,
+corresponding to header levels 1-6. For example:
+
+    # This is an H1
+
+    ## This is an H2
+
+    ###### This is an H6
+
+Optionally, you may "close" atx-style headers. This is purely
+cosmetic -- you can use this if you think it looks better. The
+closing hashes don't even need to match the number of hashes
+used to open the header. (The number of opening hashes
+determines the header level.) :
+
+    # This is an H1 #
+
+    ## This is an H2 ##
+
+    ### This is an H3 ######
+
+
+<h3 id="blockquote">Blockquotes</h3>
+
+Markdown uses email-style `>` characters for blockquoting. If you're
+familiar with quoting passages of text in an email message, then you
+know how to create a blockquote in Markdown. It looks best if you hard
+wrap the text and put a `>` before every line:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+    > 
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    > id sem consectetuer libero luctus adipiscing.
+
+Markdown allows you to be lazy and only put the `>` before the first
+line of a hard-wrapped paragraph:
+
+    > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+    consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+    > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+    id sem consectetuer libero luctus adipiscing.
+
+Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
+adding additional levels of `>`:
+
+    > This is the first level of quoting.
+    >
+    > > This is nested blockquote.
+    >
+    > Back to the first level.
+
+Blockquotes can contain other Markdown elements, including headers, lists,
+and code blocks:
+
+	> ## This is a header.
+	> 
+	> 1.   This is the first list item.
+	> 2.   This is the second list item.
+	> 
+	> Here's some example code:
+	> 
+	>     return shell_exec("echo $input | $markdown_script");
+
+Any decent text editor should make email-style quoting easy. For
+example, with BBEdit, you can make a selection and choose Increase
+Quote Level from the Text menu.
+
+
+<h3 id="list">Lists</h3>
+
+Markdown supports ordered (numbered) and unordered (bulleted) lists.
+
+Unordered lists use asterisks, pluses, and hyphens -- interchangably
+-- as list markers:
+
+    *   Red
+    *   Green
+    *   Blue
+
+is equivalent to:
+
+    +   Red
+    +   Green
+    +   Blue
+
+and:
+
+    -   Red
+    -   Green
+    -   Blue
+
+Ordered lists use numbers followed by periods:
+
+    1.  Bird
+    2.  McHale
+    3.  Parish
+
+It's important to note that the actual numbers you use to mark the
+list have no effect on the HTML output Markdown produces. The HTML
+Markdown produces from the above list is:
+
+    <ol>
+    <li>Bird</li>
+    <li>McHale</li>
+    <li>Parish</li>
+    </ol>
+
+If you instead wrote the list in Markdown like this:
+
+    1.  Bird
+    1.  McHale
+    1.  Parish
+
+or even:
+
+    3. Bird
+    1. McHale
+    8. Parish
+
+you'd get the exact same HTML output. The point is, if you want to,
+you can use ordinal numbers in your ordered Markdown lists, so that
+the numbers in your source match the numbers in your published HTML.
+But if you want to be lazy, you don't have to.
+
+If you do use lazy list numbering, however, you should still start the
+list with the number 1. At some point in the future, Markdown may support
+starting ordered lists at an arbitrary number.
+
+List markers typically start at the left margin, but may be indented by
+up to three spaces. List markers must be followed by one or more spaces
+or a tab.
+
+To make lists look nice, you can wrap items with hanging indents:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+        Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+        viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+        Suspendisse id sem consectetuer libero luctus adipiscing.
+
+But if you want to be lazy, you don't have to:
+
+    *   Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+    Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+    viverra nec, fringilla in, laoreet vitae, risus.
+    *   Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+    Suspendisse id sem consectetuer libero luctus adipiscing.
+
+If list items are separated by blank lines, Markdown will wrap the
+items in `<p>` tags in the HTML output. For example, this input:
+
+    *   Bird
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li>Bird</li>
+    <li>Magic</li>
+    </ul>
+
+But this:
+
+    *   Bird
+
+    *   Magic
+
+will turn into:
+
+    <ul>
+    <li><p>Bird</p></li>
+    <li><p>Magic</p></li>
+    </ul>
+
+List items may consist of multiple paragraphs. Each subsequent
+paragraph in a list item must be intended by either 4 spaces
+or one tab:
+
+    1.  This is a list item with two paragraphs. Lorem ipsum dolor
+        sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+        mi posuere lectus.
+
+        Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+        vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+        sit amet velit.
+
+    2.  Suspendisse id sem consectetuer libero luctus adipiscing.
+
+It looks nice if you indent every line of the subsequent
+paragraphs, but here again, Markdown will allow you to be
+lazy:
+
+    *   This is a list item with two paragraphs.
+
+        This is the second paragraph in the list item. You're
+    only required to indent the first line. Lorem ipsum dolor
+    sit amet, consectetuer adipiscing elit.
+
+    *   Another item in the same list.
+
+To put a blockquote within a list item, the blockquote's `>`
+delimiters need to be indented:
+
+    *   A list item with a blockquote:
+
+        > This is a blockquote
+        > inside a list item.
+
+To put a code block within a list item, the code block needs
+to be indented *twice* -- 8 spaces or two tabs:
+
+    *   A list item with a code block:
+
+            <code goes here>
+
+
+It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:
+
+    1986. What a great season.
+
+In other words, a *number-period-space* sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:
+
+    1986\. What a great season.
+
+
+
+<h3 id="precode">Code Blocks</h3>
+
+Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both `<pre>` and `<code>` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+    This is a normal paragraph:
+
+        This is a code block.
+
+Markdown will generate:
+
+    <p>This is a normal paragraph:</p>
+
+    <pre><code>This is a code block.
+    </code></pre>
+
+One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:
+
+    Here is an example of AppleScript:
+
+        tell application "Foo"
+            beep
+        end tell
+
+will turn into:
+
+    <p>Here is an example of AppleScript:</p>
+
+    <pre><code>tell application "Foo"
+        beep
+    end tell
+    </code></pre>
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+        <div class="footer">
+            &copy; 2004 Foo Corporation
+        </div>
+
+will turn into:
+
+    <pre><code>&lt;div class="footer"&gt;
+        &amp;copy; 2004 Foo Corporation
+    &lt;/div&gt;
+    </code></pre>
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+
+
+<h3 id="hr">Horizontal Rules</h3>
+
+You can produce a horizontal rule tag (`<hr />`) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:
+
+    * * *
+
+    ***
+
+    *****
+	
+    - - -
+
+    ---------------------------------------
+
+	_ _ _
+
+
+* * *
+
+<h2 id="span">Span Elements</h2>
+
+<h3 id="link">Links</h3>
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+    This is [an example](http://example.com/ "Title") inline link.
+
+    [This link](http://example.net/) has no title attribute.
+
+Will produce:
+
+    <p>This is <a href="http://example.com/" title="Title">
+    an example</a> inline link.</p>
+
+    <p><a href="http://example.net/">This link</a> has no
+    title attribute.</p>
+
+If you're referring to a local resource on the same server, you can
+use relative paths:
+
+    See my [About](/about/) page for details.
+
+Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:
+
+    This is [an example][id] reference-style link.
+
+You can optionally use a space to separate the sets of brackets:
+
+    This is [an example] [id] reference-style link.
+
+Then, anywhere in the document, you define your link label like this,
+on a line by itself:
+
+    [id]: http://example.com/  "Optional Title Here"
+
+That is:
+
+*   Square brackets containing the link identifier (optionally
+    indented from the left margin using up to three spaces);
+*   followed by a colon;
+*   followed by one or more spaces (or tabs);
+*   followed by the URL for the link;
+*   optionally followed by a title attribute for the link, enclosed
+    in double or single quotes.
+
+The link URL may, optionally, be surrounded by angle brackets:
+
+    [id]: <http://example.com/>  "Optional Title Here"
+
+You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:
+
+    [id]: http://example.com/longish/path/to/resource/here
+        "Optional Title Here"
+
+Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.
+
+Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
+
+	[link text][a]
+	[link text][A]
+
+are equivalent.
+
+The *implicit link name* shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+"Google" to the google.com web site, you could simply write:
+
+	[Google][]
+
+And then define the link:
+
+	[Google]: http://google.com/
+
+Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:
+
+	Visit [Daring Fireball][] for more information.
+
+And then define the link:
+	
+	[Daring Fireball]: http://daringfireball.net/
+
+Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.
+
+Here's an example of reference links in action:
+
+    I get 10 times more traffic from [Google] [1] than from
+    [Yahoo] [2] or [MSN] [3].
+
+      [1]: http://google.com/        "Google"
+      [2]: http://search.yahoo.com/  "Yahoo Search"
+      [3]: http://search.msn.com/    "MSN Search"
+
+Using the implicit link name shortcut, you could instead write:
+
+    I get 10 times more traffic from [Google][] than from
+    [Yahoo][] or [MSN][].
+
+      [google]: http://google.com/        "Google"
+      [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
+      [msn]:    http://search.msn.com/    "MSN Search"
+
+Both of the above examples will produce the following HTML output:
+
+    <p>I get 10 times more traffic from <a href="http://google.com/"
+    title="Google">Google</a> than from
+    <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
+    or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
+
+For comparison, here is the same paragraph written using
+Markdown's inline link style:
+
+    I get 10 times more traffic from [Google](http://google.com/ "Google")
+    than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+    [MSN](http://search.msn.com/ "MSN Search").
+
+The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.
+
+With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.
+
+
+<h3 id="em">Emphasis</h3>
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`<strong>` tag. E.g., this input:
+
+    *single asterisks*
+
+    _single underscores_
+
+    **double asterisks**
+
+    __double underscores__
+
+will produce:
+
+    <em>single asterisks</em>
+
+    <em>single underscores</em>
+
+    <strong>double asterisks</strong>
+
+    <strong>double underscores</strong>
+
+You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.
+
+Emphasis can be used in the middle of a word:
+
+    un*fucking*believable
+
+But if you surround an `*` or `_` with spaces, it'll be treated as a
+literal asterisk or underscore.
+
+To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:
+
+    \*this text is surrounded by literal asterisks\*
+
+
+
+<h3 id="code">Code</h3>
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+    Use the `printf()` function.
+
+will produce:
+
+    <p>Use the <code>printf()</code> function.</p>
+
+To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:
+
+    ``There is a literal backtick (`) here.``
+
+which will produce this:
+
+    <p><code>There is a literal backtick (`) here.</code></p>
+
+The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:
+
+	A single backtick in a code span: `` ` ``
+	
+	A backtick-delimited string in a code span: `` `foo` ``
+
+will produce:
+
+	<p>A single backtick in a code span: <code>`</code></p>
+	
+	<p>A backtick-delimited string in a code span: <code>`foo`</code></p>
+
+With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:
+
+    Please don't use any `<blink>` tags.
+
+into:
+
+    <p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
+
+You can write this:
+
+    `&#8212;` is the decimal-encoded equivalent of `&mdash;`.
+
+to produce:
+
+    <p><code>&amp;#8212;</code> is the decimal-encoded
+    equivalent of <code>&amp;mdash;</code>.</p>
+
+
+
+<h3 id="img">Images</h3>
+
+Admittedly, it's fairly difficult to devise a "natural" syntax for
+placing images into a plain text document format.
+
+Markdown uses an image syntax that is intended to resemble the syntax
+for links, allowing for two styles: *inline* and *reference*.
+
+Inline image syntax looks like this:
+
+    ![Alt text](/path/to/img.jpg)
+
+    ![Alt text](/path/to/img.jpg "Optional title")
+
+That is:
+
+*   An exclamation mark: `!`;
+*   followed by a set of square brackets, containing the `alt`
+    attribute text for the image;
+*   followed by a set of parentheses, containing the URL or path to
+    the image, and an optional `title` attribute enclosed in double
+    or single quotes.
+
+Reference-style image syntax looks like this:
+
+    ![Alt text][id]
+
+Where "id" is the name of a defined image reference. Image references
+are defined using syntax identical to link references:
+
+    [id]: url/to/image  "Optional title attribute"
+
+As of this writing, Markdown has no syntax for specifying the
+dimensions of an image; if this is important to you, you can simply
+use regular HTML `<img>` tags.
+
+
+* * *
+
+
+<h2 id="misc">Miscellaneous</h2>
+
+<h3 id="autolink">Automatic Links</h3>
+
+Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
+
+    <http://example.com/>
+    
+Markdown will turn this into:
+
+    <a href="http://example.com/">http://example.com/</a>
+
+Automatic links for email addresses work similarly, except that
+Markdown will also perform a bit of randomized decimal and hex
+entity-encoding to help obscure your address from address-harvesting
+spambots. For example, Markdown will turn this:
+
+    <address@example.com>
+
+into something like this:
+
+    <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
+    &#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
+    &#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
+    &#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
+
+which will render in a browser as a clickable link to "address@example.com".
+
+(This sort of entity-encoding trick will indeed fool many, if not
+most, address-harvesting bots, but it definitely won't fool all of
+them. It's better than nothing, but an address published in this way
+will probably eventually start receiving spam.)
+
+
+
+<h3 id="backslash">Backslash Escapes</h3>
+
+Markdown allows you to use backslash escapes to generate literal
+characters which would otherwise have special meaning in Markdown's
+formatting syntax. For example, if you wanted to surround a word with
+literal asterisks (instead of an HTML `<em>` tag), you can backslashes
+before the asterisks, like this:
+
+    \*literal asterisks\*
+
+Markdown provides backslash escapes for the following characters:
+
+    \   backslash
+    `   backtick
+    *   asterisk
+    _   underscore
+    {}  curly braces
+    []  square brackets
+    ()  parentheses
+    #   hash mark
+	+	plus sign
+	-	minus sign (hyphen)
+    .   dot
+    !   exclamation mark
+
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.html b/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.html
new file mode 100644
index 0000000..538bb4f
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.html	
@@ -0,0 +1,9 @@
+<blockquote>
+<p>foo</p>
+
+<blockquote>
+<p>bar</p>
+</blockquote>
+
+<p>foo</p>
+</blockquote>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.text b/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.text
new file mode 100644
index 0000000..ed3c624
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Nested blockquotes.text	
@@ -0,0 +1,5 @@
+> foo
+>
+> > bar
+>
+> foo
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.html b/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.html
new file mode 100644
index 0000000..d6fa427
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.html	
@@ -0,0 +1,166 @@
+<h2>Unordered</h2>
+
+<p>Asterisks tight:</p>
+
+<ul>
+<li>asterisk 1</li>
+<li>asterisk 2</li>
+<li>asterisk 3</li>
+</ul>
+
+<p>Asterisks loose:</p>
+
+<ul>
+<li><p>asterisk 1</p></li>
+
+<li><p>asterisk 2</p></li>
+
+<li><p>asterisk 3</p></li>
+</ul>
+
+<hr>
+
+<p>Pluses tight:</p>
+
+<ul>
+<li>Plus 1</li>
+<li>Plus 2</li>
+<li>Plus 3</li>
+</ul>
+
+<p>Pluses loose:</p>
+
+<ul>
+<li><p>Plus 1</p></li>
+
+<li><p>Plus 2</p></li>
+
+<li><p>Plus 3</p></li>
+</ul>
+
+<hr>
+
+<p>Minuses tight:</p>
+
+<ul>
+<li>Minus 1</li>
+<li>Minus 2</li>
+<li>Minus 3</li>
+</ul>
+
+<p>Minuses loose:</p>
+
+<ul>
+<li><p>Minus 1</p></li>
+
+<li><p>Minus 2</p></li>
+
+<li><p>Minus 3</p></li>
+</ul>
+
+<h2>Ordered</h2>
+
+<p>Tight:</p>
+
+<ol>
+<li>First</li>
+<li>Second</li>
+<li>Third</li>
+</ol>
+
+<p>and:</p>
+
+<ol>
+<li>One</li>
+<li>Two</li>
+<li>Three</li>
+</ol>
+
+<p>Loose using tabs:</p>
+
+<ol>
+<li><p>First</p></li>
+
+<li><p>Second</p></li>
+
+<li><p>Third</p></li>
+</ol>
+
+<p>and using spaces:</p>
+
+<ol>
+<li><p>One</p></li>
+
+<li><p>Two</p></li>
+
+<li><p>Three</p></li>
+</ol>
+
+<p>Multiple paragraphs:</p>
+
+<ol>
+<li><p>Item 1, graf one.</p>
+
+<p>Item 2. graf two. The quick brown fox jumped over the lazy dog's
+back.</p></li>
+
+<li><p>Item 2.</p></li>
+
+<li><p>Item 3.</p></li>
+</ol>
+
+<h2>Nested</h2>
+
+<ul>
+<li>Tab
+
+<ul>
+<li>Tab
+
+<ul>
+<li>Tab</li>
+</ul></li>
+</ul></li>
+</ul>
+
+<p>Here's another:</p>
+
+<ol>
+<li>First</li>
+<li>Second:
+
+<ul>
+<li>Fee</li>
+<li>Fie</li>
+<li>Foe</li>
+</ul></li>
+<li>Third</li>
+</ol>
+
+<p>Same thing but with paragraphs:</p>
+
+<ol>
+<li><p>First</p></li>
+
+<li><p>Second:</p>
+
+<ul>
+<li>Fee</li>
+<li>Fie</li>
+<li>Foe</li>
+</ul></li>
+
+<li><p>Third</p></li>
+</ol>
+
+<p>This was an error in Markdown 1.0.1:</p>
+
+<ul>
+<li><p>this</p>
+
+<ul>
+<li>sub</li>
+</ul>
+
+<p>that</p></li>
+</ul>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.text b/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.text
new file mode 100644
index 0000000..7f3b497
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Ordered and unordered lists.text	
@@ -0,0 +1,131 @@
+## Unordered
+
+Asterisks tight:
+
+*	asterisk 1
+*	asterisk 2
+*	asterisk 3
+
+
+Asterisks loose:
+
+*	asterisk 1
+
+*	asterisk 2
+
+*	asterisk 3
+
+* * *
+
+Pluses tight:
+
++	Plus 1
++	Plus 2
++	Plus 3
+
+
+Pluses loose:
+
++	Plus 1
+
++	Plus 2
+
++	Plus 3
+
+* * *
+
+
+Minuses tight:
+
+-	Minus 1
+-	Minus 2
+-	Minus 3
+
+
+Minuses loose:
+
+-	Minus 1
+
+-	Minus 2
+
+-	Minus 3
+
+
+## Ordered
+
+Tight:
+
+1.	First
+2.	Second
+3.	Third
+
+and:
+
+1. One
+2. Two
+3. Three
+
+
+Loose using tabs:
+
+1.	First
+
+2.	Second
+
+3.	Third
+
+and using spaces:
+
+1. One
+
+2. Two
+
+3. Three
+
+Multiple paragraphs:
+
+1.	Item 1, graf one.
+
+	Item 2. graf two. The quick brown fox jumped over the lazy dog's
+	back.
+	
+2.	Item 2.
+
+3.	Item 3.
+
+
+
+## Nested
+
+*	Tab
+	*	Tab
+		*	Tab
+
+Here's another:
+
+1. First
+2. Second:
+	* Fee
+	* Fie
+	* Foe
+3. Third
+
+Same thing but with paragraphs:
+
+1. First
+
+2. Second:
+	* Fee
+	* Fie
+	* Foe
+
+3. Third
+
+
+This was an error in Markdown 1.0.1:
+
+*	this
+
+	*	sub
+
+	that
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.html b/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.html
new file mode 100644
index 0000000..71ec78c
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.html	
@@ -0,0 +1,7 @@
+<p><strong><em>This is strong and em.</em></strong></p>
+
+<p>So is <strong><em>this</em></strong> word.</p>
+
+<p><strong><em>This is strong and em.</em></strong></p>
+
+<p>So is <strong><em>this</em></strong> word.</p>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.text b/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.text
new file mode 100644
index 0000000..95ee690
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Strong and em together.text	
@@ -0,0 +1,7 @@
+***This is strong and em.***
+
+So is ***this*** word.
+
+___This is strong and em.___
+
+So is ___this___ word.
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Tabs.html b/vendor/src/github.com/russross/blackfriday/testdata/Tabs.html
new file mode 100644
index 0000000..64006d9
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Tabs.html
@@ -0,0 +1,26 @@
+<ul>
+<li><p>this is a list item
+indented with tabs</p></li>
+
+<li><p>this is a list item
+indented with spaces</p></li>
+</ul>
+
+<p>Code:</p>
+
+<pre><code>this code block is indented by one tab
+</code></pre>
+
+<p>And:</p>
+
+<pre><code>    this code block is indented by two tabs
+</code></pre>
+
+<p>And:</p>
+
+<pre><code>+   this is an example list item
+    indented with tabs
+
++   this is an example list item
+    indented with spaces
+</code></pre>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Tabs.text b/vendor/src/github.com/russross/blackfriday/testdata/Tabs.text
new file mode 100644
index 0000000..589d113
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Tabs.text
@@ -0,0 +1,21 @@
++	this is a list item
+	indented with tabs
+
++   this is a list item
+    indented with spaces
+
+Code:
+
+	this code block is indented by one tab
+
+And:
+
+		this code block is indented by two tabs
+
+And:
+
+	+	this is an example list item
+		indented with tabs
+	
+	+   this is an example list item
+	    indented with spaces
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.html b/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.html
new file mode 100644
index 0000000..9c45b69
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.html
@@ -0,0 +1,9 @@
+<blockquote>
+<p>A list within a blockquote:</p>
+
+<ul>
+<li>asterisk 1</li>
+<li>asterisk 2</li>
+<li>asterisk 3</li>
+</ul>
+</blockquote>
diff --git a/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.text b/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.text
new file mode 100644
index 0000000..5f18b8d
--- /dev/null
+++ b/vendor/src/github.com/russross/blackfriday/testdata/Tidyness.text
@@ -0,0 +1,5 @@
+> A list within a blockquote:
+> 
+> *	asterisk 1
+> *	asterisk 2
+> *	asterisk 3
diff --git a/vendor/src/github.com/shurcooL/sanitized_anchor_name/.travis.yml b/vendor/src/github.com/shurcooL/sanitized_anchor_name/.travis.yml
new file mode 100644
index 0000000..aaee9cf
--- /dev/null
+++ b/vendor/src/github.com/shurcooL/sanitized_anchor_name/.travis.yml
@@ -0,0 +1,10 @@
+language: go
+go:
+  - 1.4
+install:
+  - go get golang.org/x/tools/cmd/vet
+script:
+  - go get -t -v ./...
+  - diff -u <(echo -n) <(gofmt -d ./)
+  - go tool vet ./
+  - go test -v -race ./...
diff --git a/vendor/src/github.com/shurcooL/sanitized_anchor_name/README.md b/vendor/src/github.com/shurcooL/sanitized_anchor_name/README.md
new file mode 100644
index 0000000..089c440
--- /dev/null
+++ b/vendor/src/github.com/shurcooL/sanitized_anchor_name/README.md
@@ -0,0 +1,25 @@
+sanitized_anchor_name [![Build Status](https://travis-ci.org/shurcooL/sanitized_anchor_name.svg?branch=master)](https://travis-ci.org/shurcooL/sanitized_anchor_name)
+=====================
+
+Package `sanitized_anchor_name` provides a func to create sanitized anchor names.
+
+Its logic can be reused by multiple packages to create interoperable anchor names and links to those anchors.
+
+At this time, it does not try to ensure that generated anchor names are unique, that responsibility falls on the caller.
+
+Example
+=======
+
+```Go
+anchorName := sanitized_anchor_name.Create("This is a header")
+
+fmt.Println(anchorName)
+
+// Output:
+// this-is-a-header
+```
+
+License
+-------
+
+- [MIT License](http://opensource.org/licenses/mit-license.php)
diff --git a/vendor/src/github.com/shurcooL/sanitized_anchor_name/main.go b/vendor/src/github.com/shurcooL/sanitized_anchor_name/main.go
new file mode 100644
index 0000000..72a8753
--- /dev/null
+++ b/vendor/src/github.com/shurcooL/sanitized_anchor_name/main.go
@@ -0,0 +1,29 @@
+// Package sanitized_anchor_name provides a func to create sanitized anchor names.
+//
+// Its logic can be reused by multiple packages to create interoperable anchor names
+// and links to those anchors.
+//
+// At this time, it does not try to ensure that generated anchor names
+// are unique, that responsibility falls on the caller.
+package sanitized_anchor_name // import "github.com/shurcooL/sanitized_anchor_name"
+
+import "unicode"
+
+// Create returns a sanitized anchor name for the given text.
+func Create(text string) string {
+	var anchorName []rune
+	var futureDash = false
+	for _, r := range []rune(text) {
+		switch {
+		case unicode.IsLetter(r) || unicode.IsNumber(r):
+			if futureDash && len(anchorName) > 0 {
+				anchorName = append(anchorName, '-')
+			}
+			futureDash = false
+			anchorName = append(anchorName, unicode.ToLower(r))
+		default:
+			futureDash = true
+		}
+	}
+	return string(anchorName)
+}
diff --git a/vendor/src/github.com/shurcooL/sanitized_anchor_name/main_test.go b/vendor/src/github.com/shurcooL/sanitized_anchor_name/main_test.go
new file mode 100644
index 0000000..ad03201
--- /dev/null
+++ b/vendor/src/github.com/shurcooL/sanitized_anchor_name/main_test.go
@@ -0,0 +1,35 @@
+package sanitized_anchor_name_test
+
+import (
+	"fmt"
+
+	"github.com/shurcooL/sanitized_anchor_name"
+)
+
+func ExampleCreate() {
+	anchorName := sanitized_anchor_name.Create("This is a header")
+
+	fmt.Println(anchorName)
+
+	// Output:
+	// this-is-a-header
+}
+
+func ExampleCreate2() {
+	fmt.Println(sanitized_anchor_name.Create("This is a header"))
+	fmt.Println(sanitized_anchor_name.Create("This is also          a header"))
+	fmt.Println(sanitized_anchor_name.Create("main.go"))
+	fmt.Println(sanitized_anchor_name.Create("Article 123"))
+	fmt.Println(sanitized_anchor_name.Create("<- Let's try this, shall we?"))
+	fmt.Printf("%q\n", sanitized_anchor_name.Create("        "))
+	fmt.Println(sanitized_anchor_name.Create("Hello, 世界"))
+
+	// Output:
+	// this-is-a-header
+	// this-is-also-a-header
+	// main-go
+	// article-123
+	// let-s-try-this-shall-we
+	// ""
+	// hello-世界
+}
-- 
1.8.3.1