diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c)2011, Michael Snoyman
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of Michael Snoyman nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+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
+OWNER 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/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/Text/Markdown.hs b/Text/Markdown.hs
new file mode 100644
--- /dev/null
+++ b/Text/Markdown.hs
@@ -0,0 +1,158 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE RankNTypes #-}
+module Text.Markdown
+    ( -- * Functions
+      markdown
+      -- * Settings
+    , MarkdownSettings
+    , msXssProtect
+    , msStandaloneHtml
+    , msFencedHandlers
+      -- * Newtype
+    , Markdown (..)
+      -- * Fenced handlers
+    , FencedHandler (..)
+    , codeFencedHandler
+    , htmlFencedHandler
+      -- * Convenience re-exports
+    , def
+    ) where
+
+import Text.Markdown.Inline
+import Text.Markdown.Block
+import Text.Markdown.Types
+import Text.Highlighting.Kate
+import Prelude hiding                              (sequence, takeWhile)
+import Data.Default                                (Default (..))
+import Data.Text                                   (Text, unpack)
+import qualified Data.Text.Lazy as TL
+import Text.Blaze.Html                             (ToMarkup (..), Html)
+import Text.Blaze.Html.Renderer.Text               (renderHtml)
+import Data.Conduit
+import qualified Data.Conduit.List as CL
+import Data.Monoid                                 (Monoid (mappend, mempty, mconcat))
+import Data.Functor.Identity                       (runIdentity)
+import qualified Text.Blaze.Html5 as H
+import qualified Text.Blaze.Html5.Attributes as HA
+import Text.HTML.SanitizeXSS                       (sanitizeBalance)
+import qualified Data.Map as Map
+import Data.String                                 (IsString)
+
+-- | A newtype wrapper providing a @ToHtml@ instance.
+newtype Markdown = Markdown TL.Text
+  deriving(Monoid, IsString)
+
+instance ToMarkup Markdown where
+    toMarkup (Markdown t) = markdown def t
+
+-- | Convert the given textual markdown content to HTML.
+--
+-- >>> :set -XOverloadedStrings
+-- >>> import Text.Blaze.Html.Renderer.Text
+-- >>> renderHtml $ markdown def "# Hello World!"
+-- "<h1>Hello World!</h1>"
+--
+-- >>> renderHtml $ markdown def { msXssProtect = False } "<script>alert('evil')</script>"
+-- "<script>alert('evil')</script>"
+markdown :: MarkdownSettings -> TL.Text -> Html
+markdown ms tl =
+       sanitize
+     $ runIdentity
+     $ CL.sourceList blocksH
+    $= toHtmlB ms
+    $$ CL.fold mappend mempty
+  where
+    sanitize
+        | msXssProtect ms = preEscapedToMarkup . sanitizeBalance . TL.toStrict . renderHtml
+        | otherwise = id
+    fixBlock :: Block Text -> Block Html
+    fixBlock = fmap $ toHtmlI ms . toInline refs
+
+    blocksH :: [Block Html]
+    blocksH = map fixBlock blocks
+
+    blocks :: [Block Text]
+    blocks = runIdentity
+           $ CL.sourceList (TL.toChunks tl)
+          $$ toBlocks ms
+          =$ CL.consume
+
+    refs =
+        Map.unions $ map toRef blocks
+      where
+        toRef (BlockReference x y) = Map.singleton x y
+        toRef _ = Map.empty
+
+data MState = NoState | InList ListType
+
+toHtmlB :: Monad m => MarkdownSettings -> Conduit (Block Html) m Html
+toHtmlB ms =
+    loop NoState
+  where
+    loop state = await >>= maybe
+        (closeState state)
+        (\x -> do
+            state' <- getState state x
+            yield $ go x
+            loop state')
+
+    closeState NoState = return ()
+    closeState (InList Unordered) = yield $ escape "</ul>"
+    closeState (InList Ordered) = yield $ escape "</ol>"
+
+    getState NoState (BlockList ltype _) = do
+        yield $ escape $
+            case ltype of
+                Unordered -> "<ul>"
+                Ordered -> "<ol>"
+        return $ InList ltype
+    getState NoState _ = return NoState
+    getState state@(InList lt1) b@(BlockList lt2 _)
+        | lt1 == lt2 = return state
+        | otherwise = closeState state >> getState NoState b
+    getState state@(InList _) _ = closeState state >> return NoState
+
+    go (BlockPara h) = H.p h
+    go (BlockPlainText h) = h
+    go (BlockList _ (Left h)) = H.li h
+    go (BlockList _ (Right bs)) = H.li $ blocksToHtml bs
+    go (BlockHtml t) = escape t
+    go (BlockCode Nothing t) = H.pre $ H.code $ toMarkup t
+    go (BlockCode (Just lang) t) = H.figure $ toHighlighted (unpack lang) (unpack t)
+    go (BlockQuote bs) = H.blockquote $ blocksToHtml bs
+    go BlockRule = H.hr
+    go (BlockHeading level h) =
+        wrap level h
+      where
+       wrap 1 = H.h1
+       wrap 2 = H.h2
+       wrap 3 = H.h3
+       wrap 4 = H.h4
+       wrap 5 = H.h5
+       wrap _ = H.h6
+    go BlockReference{} = return ()
+
+    toHighlighted l t' = toMarkup $ formatHtmlBlock (defaultFormatOpts { numberLines = True }) $ highlightAs l t'
+    blocksToHtml bs = runIdentity $ mapM_ yield bs $$ toHtmlB ms =$ CL.fold mappend mempty
+
+escape :: Text -> Html
+escape = preEscapedToMarkup
+
+toHtmlI :: MarkdownSettings -> [Inline] -> Html
+toHtmlI ms is0
+    | msXssProtect ms = escape $ sanitizeBalance $ TL.toStrict $ renderHtml final
+    | otherwise = final
+  where
+    final = gos is0
+    gos = mconcat . map go
+
+    go (InlineText t) = toMarkup t
+    go (InlineItalic is) = H.i $ gos is
+    go (InlineBold is) = H.b $ gos is
+    go (InlineCode t) = H.code $ toMarkup t
+    go (InlineLink url Nothing content) = H.a H.! HA.href (H.toValue url) $ gos content
+    go (InlineLink url (Just title) content) = H.a H.! HA.href (H.toValue url) H.! HA.title (H.toValue title) $ gos content
+    go (InlineImage url Nothing content) = H.img H.! HA.src (H.toValue url) H.! HA.alt (H.toValue content)
+    go (InlineImage url (Just title) content) = H.img H.! HA.src (H.toValue url) H.! HA.alt (H.toValue content) H.! HA.title (H.toValue title)
+    go (InlineHtml t) = escape t
diff --git a/Text/Markdown/Block.hs b/Text/Markdown/Block.hs
new file mode 100644
--- /dev/null
+++ b/Text/Markdown/Block.hs
@@ -0,0 +1,324 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE PatternGuards #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE CPP #-}
+{-# OPTIONS_HADDOCK hide #-}
+module Text.Markdown.Block
+    ( Block (..)
+    , ListType (..)
+    , toBlocks
+    ) where
+
+import Prelude
+#if MIN_VERSION_conduit(1, 0, 0)
+import Data.Conduit
+#else
+import Data.Conduit hiding ((=$=))
+import Data.Conduit.Internal (pipeL)
+#endif
+import qualified Data.Conduit.Text as CT
+import qualified Data.Conduit.List as CL
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Functor.Identity (runIdentity)
+import Data.Char (isDigit)
+import Text.Markdown.Types
+import qualified Data.Set as Set
+import qualified Data.Map as Map
+
+#if !MIN_VERSION_conduit(1, 0, 0)
+(=$=) :: Monad m => Pipe a a b x m y -> Pipe b b c y m z -> Pipe a a c x m z
+(=$=) = pipeL
+#endif
+
+toBlocks :: Monad m => MarkdownSettings -> Conduit Text m (Block Text)
+toBlocks ms =
+    mapOutput fixWS CT.lines =$= toBlocksLines ms
+  where
+    fixWS = T.pack . go 0 . T.unpack
+
+    go _ [] = []
+    go i ('\r':cs) = go i cs
+    go i ('\t':cs) =
+        (replicate j ' ') ++ go (i + j) cs
+      where
+        j = 4 - (i `mod` 4)
+    go i (c:cs) = c : go (i + 1) cs
+
+toBlocksLines :: Monad m => MarkdownSettings -> Conduit Text m (Block Text)
+toBlocksLines ms = awaitForever (start ms) =$= tightenLists
+
+tightenLists :: Monad m => Conduit (Either Blank (Block Text)) m (Block Text)
+tightenLists =
+    go Nothing
+  where
+    go mTightList =
+        await >>= maybe (return ()) go'
+      where
+        go' (Left Blank) = go mTightList
+        go' (Right (BlockList ltNew contents)) =
+            case mTightList of
+                Just (ltOld, isTight) | ltOld == ltNew -> do
+                    yield $ BlockList ltNew $ (if isTight then tighten else untighten) contents
+                    go mTightList
+                _ -> do
+                    isTight <- checkTight ltNew False
+                    yield $ BlockList ltNew $ (if isTight then tighten else untighten) contents
+                    go $ Just (ltNew, isTight)
+        go' (Right b) = yield b >> go Nothing
+
+    tighten (Right [BlockPara t]) = Left t
+    tighten (Right []) = Left T.empty
+    tighten x = x
+
+    untighten (Left t) = Right [BlockPara t]
+    untighten x = x
+
+    checkTight lt sawBlank = do
+        await >>= maybe (return $ not sawBlank) go'
+      where
+        go' (Left Blank) = checkTight lt True
+        go' b@(Right (BlockList ltNext _)) | ltNext == lt = do
+            leftover b
+            return $ not sawBlank
+        go' b = leftover b >> return False
+
+data Blank = Blank
+
+data LineType = LineList ListType Text
+              | LineCode Text
+              | LineFenced Text FencedHandler -- ^ terminator, language
+              | LineBlockQuote Text
+              | LineHeading Int Text
+              | LineBlank
+              | LineText Text
+              | LineRule
+              | LineHtml Text
+              | LineReference Text Text -- ^ name, destination
+
+lineType :: MarkdownSettings -> Text -> LineType
+lineType ms t
+    | T.null $ T.strip t = LineBlank
+    | Just (term, fh) <- getFenced (Map.toList $ msFencedHandlers ms) t = LineFenced term fh
+    | Just t' <- T.stripPrefix "> " t = LineBlockQuote t'
+    | Just (level, t') <- stripHeading t = LineHeading level t'
+    | Just t' <- T.stripPrefix "    " t = LineCode t'
+    | isRule t = LineRule
+    | isHtmlStart t = LineHtml t
+    | Just (ltype, t') <- listStart t = LineList ltype t'
+    | Just (name, dest) <- getReference t = LineReference name dest
+    | otherwise = LineText t
+  where
+    getFenced [] _ = Nothing
+    getFenced ((x, fh):xs) t'
+        | Just rest <- T.stripPrefix x t' = Just (x, fh $ T.strip rest)
+        | otherwise = getFenced xs t'
+
+    isRule :: Text -> Bool
+    isRule =
+        go . T.strip
+      where
+        go "* * *" = True
+        go "***" = True
+        go "*****" = True
+        go "- - -" = True
+        go "---" = True
+        go "___" = True
+        go "_ _ _" = True
+        go t' = T.length (T.takeWhile (== '-') t') >= 5
+
+    stripHeading :: Text -> Maybe (Int, Text)
+    stripHeading t'
+        | T.null x = Nothing
+        | otherwise = Just (T.length x, T.strip $ T.dropWhileEnd (== '#') y)
+      where
+        (x, y) = T.span (== '#') t'
+
+    getReference :: Text -> Maybe (Text, Text)
+    getReference a = do
+        b <- T.stripPrefix "[" $ T.dropWhile (== ' ') a
+        let (name, c) = T.break (== ']') b
+        d <- T.stripPrefix "]:" c
+        Just (name, T.strip d)
+
+start :: Monad m => MarkdownSettings -> Text -> Conduit Text m (Either Blank (Block Text))
+start ms t =
+    go $ lineType ms t
+  where
+    go LineBlank = yield $ Left Blank
+    go (LineFenced term fh) = do
+        (finished, ls) <- takeTillConsume (== term)
+        case finished of
+            Just _ -> do
+                let block =
+                        case fh of
+                            FHRaw fh' -> fh' $ T.intercalate "\n" ls
+                            FHParsed fh' -> fh' $ runIdentity $ mapM_ yield ls $$ toBlocksLines ms =$ CL.consume
+                mapM_ (yield . Right) block
+            Nothing -> mapM_ leftover (reverse $ T.cons ' ' t : ls)
+    go (LineBlockQuote t') = do
+        ls <- takeQuotes =$= CL.consume
+        let blocks = runIdentity $ mapM_ yield (t' : ls) $$ toBlocksLines ms =$ CL.consume
+        yield $ Right $ BlockQuote blocks
+    go (LineHeading level t') = yield $ Right $ BlockHeading level t'
+    go (LineCode t') = do
+        ls <- getIndented 4 =$= CL.consume
+        yield $ Right $ BlockCode Nothing $ T.intercalate "\n" $ t' : ls
+    go LineRule = yield $ Right BlockRule
+    go (LineHtml t') = do
+        if t' `Set.member` msStandaloneHtml ms
+            then yield $ Right $ BlockHtml t'
+            else do
+                ls <- takeTill (T.null . T.strip) =$= CL.consume
+                yield $ Right $ BlockHtml $ T.intercalate "\n" $ t' : ls
+    go (LineList ltype t') = do
+        t2 <- CL.peek
+        case fmap (lineType ms) t2 of
+            -- If the next line is a non-indented text line, then we have a
+            -- lazy list.
+            Just (LineText t2') | T.null (T.takeWhile (== ' ') t2') -> do
+                CL.drop 1
+                -- Get all of the non-indented lines.
+                let loop front = do
+                        x <- await
+                        case x of
+                            Nothing -> return $ front []
+                            Just y ->
+                                case lineType ms y of
+                                    LineText z -> loop (front . (z:))
+                                    _ -> leftover y >> return (front [])
+                ls <- loop (\rest -> T.dropWhile (== ' ') t' : t2' : rest)
+                yield $ Right $ BlockList ltype $ Right [BlockPara $ T.intercalate "\n" ls]
+            -- If the next line is an indented list, then we have a sublist. I
+            -- disagree with this interpretation of Markdown, but it's the way
+            -- that Github implements things, so we will too.
+            _ | Just t2' <- t2
+              , Just t2'' <- T.stripPrefix "    " t2'
+              , LineList _ltype' _t2''' <- lineType ms t2'' -> do
+                ls <- getIndented 4 =$= CL.consume
+                let blocks = runIdentity $ mapM_ yield ls $$ toBlocksLines ms =$ CL.consume
+                let addPlainText
+                        | T.null $ T.strip t' = id
+                        | otherwise = (BlockPlainText (T.strip t'):)
+                yield $ Right $ BlockList ltype $ Right $ addPlainText blocks
+            _ -> do
+                let t'' = T.dropWhile (== ' ') t'
+                let leader = T.length t - T.length t''
+                ls <- getIndented leader =$= CL.consume
+                let blocks = runIdentity $ mapM_ yield (t'' : ls) $$ toBlocksLines ms =$ CL.consume
+                yield $ Right $ BlockList ltype $ Right blocks
+    go (LineReference x y) = yield $ Right $ BlockReference x y
+    go (LineText t') = do
+        -- Check for underline headings
+        let getUnderline :: Text -> Maybe Int
+            getUnderline s
+                | T.length s < 2 = Nothing
+                | T.all (== '=') s = Just 1
+                | T.all (== '-') s = Just 2
+                | otherwise = Nothing
+        t2 <- CL.peek
+        case t2 >>= getUnderline of
+            Just level -> do
+                CL.drop 1
+                yield $ Right $ BlockHeading level t'
+            Nothing -> do
+                let listStartIndent x =
+                        case listStart x of
+                            Just (_, y) -> T.take 2 y == "  "
+                            Nothing -> False
+                    isNonPara LineBlank = True
+                    isNonPara LineFenced{} = True
+                    isNonPara _ = False
+                (mfinal, ls) <- takeTillConsume (\x -> isNonPara (lineType ms x) || listStartIndent x)
+                maybe (return ()) leftover mfinal
+                yield $ Right $ BlockPara $ T.intercalate "\n" $ t' : ls
+
+isHtmlStart :: T.Text -> Bool
+isHtmlStart t =
+    case T.stripPrefix "<" t of
+        Nothing -> False
+        Just t' ->
+            let (name, rest) = T.break (\c -> c `elem` " >") t'
+             in T.all isValidTagName name &&
+                not (T.null name) &&
+                (not ("/" `T.isPrefixOf` rest) || ("/>" `T.isPrefixOf` rest))
+  where
+    isValidTagName :: Char -> Bool
+    isValidTagName c =
+        ('A' <= c && c <= 'Z') ||
+        ('a' <= c && c <= 'z') ||
+        ('0' <= c && c <= '9') ||
+        (c == '-') ||
+        (c == '_') ||
+        (c == '/') ||
+        (c == '!')
+
+takeTill :: Monad m => (i -> Bool) -> Conduit i m i
+takeTill f =
+    loop
+  where
+    loop = await >>= maybe (return ()) (\x -> if f x then return () else yield x >> loop)
+
+--takeTillConsume :: Monad m => (i -> Bool) -> Consumer i m (Maybe i, [i])
+takeTillConsume f =
+    loop id
+  where
+    loop front = await >>= maybe
+        (return (Nothing, front []))
+        (\x ->
+            if f x
+                then return (Just x, front [])
+                else loop (front . (x:))
+        )
+
+listStart :: Text -> Maybe (ListType, Text)
+listStart t0
+    | Just t' <- T.stripPrefix "* " t = Just (Unordered, t')
+    | Just t' <- T.stripPrefix "+ " t = Just (Unordered, t')
+    | Just t' <- T.stripPrefix "- " t = Just (Unordered, t')
+    | Just t' <- stripNumber t, Just t'' <- stripSeparator t' = Just (Ordered, t'')
+    | otherwise = Nothing
+  where
+    t = T.stripStart t0
+
+stripNumber :: Text -> Maybe Text
+stripNumber x
+    | T.null y = Nothing
+    | otherwise = Just z
+  where
+    (y, z) = T.span isDigit x
+
+stripSeparator :: Text -> Maybe Text
+stripSeparator x =
+    case T.uncons x of
+        Nothing -> Nothing
+        Just ('.', y) -> Just y
+        Just (')', y) -> Just y
+        _ -> Nothing
+
+getIndented :: Monad m => Int -> Conduit Text m Text
+getIndented leader =
+    go []
+  where
+    go blanks = await >>= maybe (mapM_ leftover blanks) (go' blanks)
+
+    go' blanks t
+        | T.null $ T.strip t = go (T.drop leader t : blanks)
+        | T.length x == leader && T.null (T.strip x) = do
+            mapM_ yield $ reverse blanks
+            yield y
+            go []
+        | otherwise = mapM_ leftover (t:blanks)
+      where
+        (x, y) = T.splitAt leader t
+
+takeQuotes :: Monad m => Conduit Text m Text
+takeQuotes =
+    await >>= maybe (return ()) go
+  where
+    go "" = return ()
+    go ">" = yield "" >> takeQuotes
+    go t
+        | Just t' <- T.stripPrefix "> " t = yield t' >> takeQuotes
+        | otherwise = yield t >> takeQuotes
diff --git a/Text/Markdown/Inline.hs b/Text/Markdown/Inline.hs
new file mode 100644
--- /dev/null
+++ b/Text/Markdown/Inline.hs
@@ -0,0 +1,232 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# OPTIONS_HADDOCK hide #-}
+module Text.Markdown.Inline
+    ( Inline (..)
+    , inlineParser
+    , toInline
+    ) where
+
+import Prelude hiding (takeWhile)
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Attoparsec.Text
+import Control.Applicative
+import Data.Monoid (Monoid, mappend)
+import qualified Data.Map as Map
+
+type RefMap = Map.Map Text Text
+
+toInline :: RefMap -> Text -> [Inline]
+toInline refmap t =
+    case parseOnly (inlineParser refmap) t of
+        Left s -> [InlineText $ T.pack s]
+        Right is -> is
+
+(<>) :: Monoid m => m -> m -> m
+(<>) = mappend
+
+data Inline = InlineText Text
+            | InlineItalic [Inline]
+            | InlineBold [Inline]
+            | InlineCode Text
+            | InlineHtml Text
+            | InlineLink Text (Maybe Text) [Inline] -- ^ URL, title, content
+            | InlineImage Text (Maybe Text) Text -- ^ URL, title, content
+    deriving (Show, Eq)
+
+inlineParser :: RefMap -> Parser [Inline]
+inlineParser = fmap combine . many . inlineAny
+
+combine :: [Inline] -> [Inline]
+combine [] = []
+combine (InlineText x:InlineText y:rest) = combine (InlineText (x <> y):rest)
+combine (InlineText x:rest) = InlineText x : combine rest
+combine (InlineItalic x:InlineItalic y:rest) = combine (InlineItalic (x <> y):rest)
+combine (InlineItalic x:rest) = InlineItalic (combine x) : combine rest
+combine (InlineBold x:InlineBold y:rest) = combine (InlineBold (x <> y):rest)
+combine (InlineBold x:rest) = InlineBold (combine x) : combine rest
+combine (InlineCode x:InlineCode y:rest) = combine (InlineCode (x <> y):rest)
+combine (InlineCode x:rest) = InlineCode x : combine rest
+combine (InlineLink u t c:rest) = InlineLink u t (combine c) : combine rest
+combine (InlineImage u t c:rest) = InlineImage u t c : combine rest
+combine (InlineHtml t:rest) = InlineHtml t : combine rest
+
+specials :: [Char]
+specials = "*_`\\[]!<&"
+
+inlineAny :: RefMap -> Parser Inline
+inlineAny refs =
+    inline refs <|> special
+  where
+    special = InlineText . T.singleton <$> satisfy (`elem` specials)
+
+inline :: RefMap -> Parser Inline
+inline refs =
+    text
+    <|> escape
+    <|> paired "**" InlineBold <|> paired "__" InlineBold
+    <|> paired "*" InlineItalic <|> paired "_" InlineItalic
+    <|> doubleCode <|> code
+    <|> link
+    <|> image
+    <|> autoLink
+    <|> html
+    <|> entity
+  where
+    inlinesTill :: Text -> Parser [Inline]
+    inlinesTill end =
+        go id
+      where
+        go front =
+            (string end *> pure (front []))
+            <|> (do
+                x <- inlineAny refs
+                go $ front . (x:))
+
+    text = InlineText <$> takeWhile1 (`notElem` specials)
+
+    paired t wrap = wrap <$> do
+        _ <- string t
+        is <- inlinesTill t
+        if null is then fail "wrapped around something missing" else return is
+
+    doubleCode = InlineCode . T.pack <$> (string "`` " *> manyTill anyChar (string " ``"))
+    code = InlineCode <$> (char '`' *> takeWhile1 (/= '`') <* char '`')
+
+    escape = InlineText . T.singleton <$> (char '\\' *> satisfy (`elem` "\\`*_{}[]()#+-.!>"))
+
+    takeBalancedBrackets =
+        T.pack <$> go (0 :: Int)
+      where
+        go i = do
+            c <- anyChar
+            case c of
+                '[' -> (c:) <$> go (i + 1)
+                ']'
+                    | i == 0 -> return []
+                    | otherwise -> (c:) <$> go (i - 1)
+                _ -> (c:) <$> go i
+
+    parseUrl = fixUrl . T.pack <$> parseUrl' (0 :: Int)
+
+    parseUrl' level
+        | level > 0 = do
+            c <- anyChar
+            let level'
+                    | c == ')' = level - 1
+                    | otherwise = level
+            c' <-
+                if c == '\\'
+                    then anyChar
+                    else return c
+            cs <- parseUrl' level'
+            return $ c' : cs
+        | otherwise = (do
+            c <- hrefChar
+            if c == '('
+                then (c:) <$> parseUrl' 1
+                else (c:) <$> parseUrl' 0) <|> return []
+
+    parseUrlTitle defRef = parseUrlTitleInline <|> parseUrlTitleRef defRef
+
+    parseUrlTitleInside endTitle = do
+        url <- parseUrl
+        mtitle <- (Just <$> title) <|> (skipSpace >> endTitle >> pure Nothing)
+        return (url, mtitle)
+      where
+        title = do
+            _ <- space
+            skipSpace
+            _ <- char '"'
+            t <- T.stripEnd . T.pack <$> go
+            return $
+                if not (T.null t) && T.last t == '"'
+                    then T.init t
+                    else t
+          where
+            go =  (char '\\' *> anyChar >>= \c -> (c:) <$> go)
+              <|> (endTitle *> return [])
+              <|> (anyChar >>= \c -> (c:) <$> go)
+
+    parseUrlTitleInline = char '(' *> parseUrlTitleInside (char ')')
+
+    parseUrlTitleRef defRef = do
+        ref' <- (skipSpace *> char '[' *> takeWhile (/= ']') <* char ']') <|> return ""
+        let ref = if T.null ref' then defRef else ref'
+        case Map.lookup (T.unwords $ T.words ref) refs of
+            Nothing -> fail "ref not found"
+            Just t -> either fail return $ parseOnly (parseUrlTitleInside endOfInput) t
+
+    link = do
+        _ <- char '['
+        rawContent <- takeBalancedBrackets
+        content <- either fail return $ parseOnly (inlineParser refs) rawContent
+        (url, mtitle) <- parseUrlTitle rawContent
+        return $ InlineLink url mtitle content
+
+    image = do
+        _ <- string "!["
+        content <- takeBalancedBrackets
+        (url, mtitle) <- parseUrlTitle content
+        return $ InlineImage url mtitle content
+
+    fixUrl t
+        | T.length t > 2 && T.head t == '<' && T.last t == '>' = T.init $ T.tail t
+        | otherwise = t
+
+    autoLink = do
+        _ <- char '<'
+        a <- string "http:" <|> string "https:"
+        b <- takeWhile1 (/= '>')
+        _ <- char '>'
+        let url = a `T.append` b
+        return $ InlineLink url Nothing [InlineText url]
+
+    html = do
+        c <- char '<'
+        t <- takeWhile1 (\x -> ('A' <= x && x <= 'Z') || ('a' <= x && x <= 'z') || x == '/')
+        if T.null t
+            then fail "invalid tag"
+            else do
+                t2 <- takeWhile (/= '>')
+                c2 <- char '>'
+                return $ InlineHtml $ T.concat
+                    [ T.singleton c
+                    , t
+                    , t2
+                    , T.singleton c2
+                    ]
+
+    entity =
+            rawent "&lt;"
+        <|> rawent "&gt;"
+        <|> rawent "&amp;"
+        <|> rawent "&quot;"
+        <|> rawent "&apos;"
+        <|> decEnt
+        <|> hexEnt
+
+    rawent t = InlineHtml <$> string t
+
+    decEnt = do
+        s <- string "&#"
+        t <- takeWhile1 $ \x -> ('0' <= x && x <= '9')
+        c <- char ';'
+        return $ InlineHtml $ T.concat
+            [ s
+            , t
+            , T.singleton c
+            ]
+
+    hexEnt = do
+        s <- string "&#x" <|> string "&#X"
+        t <- takeWhile1 $ \x -> ('0' <= x && x <= '9') || ('A' <= x && x <= 'F') || ('a' <= x && x <= 'f')
+        c <- char ';'
+        return $ InlineHtml $ T.concat
+            [ s
+            , t
+            , T.singleton c
+            ]
+
+hrefChar :: Parser Char
+hrefChar = (char '\\' *> anyChar) <|> satisfy (notInClass " )")
diff --git a/Text/Markdown/Types.hs b/Text/Markdown/Types.hs
new file mode 100644
--- /dev/null
+++ b/Text/Markdown/Types.hs
@@ -0,0 +1,119 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Text.Markdown.Types where
+
+import Data.Text (Text)
+import qualified Data.Text as T
+import Data.Default (Default (def))
+import Data.Set (Set, empty)
+import Data.Map (Map, singleton)
+import Data.Monoid (mappend)
+
+-- | A settings type providing various configuration options.
+--
+-- See <http://www.yesodweb.com/book/settings-types> for more information on
+-- settings types. In general, you can use @def@.
+data MarkdownSettings = MarkdownSettings
+    { msXssProtect :: Bool
+      -- ^ Whether to automatically apply XSS protection to embedded HTML. Default: @True@.
+    , msStandaloneHtml :: Set Text
+      -- ^ HTML snippets which stand on their own. We do not require a blank line following these pieces of HTML.
+      --
+      -- Default: empty set.
+      --
+      -- Since: 0.1.2
+    , msFencedHandlers :: Map Text (Text -> FencedHandler)
+      -- ^ Handlers for the special \"fenced\" format. This is most commonly
+      -- used for fenced code, e.g.:
+      --
+      -- > ```haskell
+      -- > main = putStrLn "Hello"
+      -- > ```
+      --
+      -- This is an extension of Markdown, but a fairly commonly used one.
+      --
+      -- This setting allows you to create new kinds of fencing. Fencing goes
+      -- into two categories: parsed and raw. Code fencing would be in the raw
+      -- category, where the contents are not treated as Markdown. Parsed will
+      -- treat the contents as Markdown and allow you to perform some kind of
+      -- modifcation to it.
+      --
+      -- For example, to create a new @\@\@\@@ fencing which wraps up the
+      -- contents in an @article@ tag, you could use:
+      --
+      -- > def { msFencedHandlers = htmlFencedHandler "@@@" (const "<article>") (const "</article")
+      -- >              `Map.union` msFencedHandlers def
+      -- >     }
+      --
+      -- Default: code fencing for @```@ and @~~~@.
+      --
+      -- Since: 0.1.2
+    }
+
+-- | See 'msFencedHandlers.
+--
+-- Since 0.1.2
+data FencedHandler = FHRaw (Text -> [Block Text])
+                     -- ^ Wrap up the given raw content.
+                   | FHParsed ([Block Text] -> [Block Text])
+                     -- ^ Wrap up the given parsed content.
+
+instance Default MarkdownSettings where
+    def = MarkdownSettings
+        { msXssProtect = True
+        , msStandaloneHtml = empty
+        , msFencedHandlers = codeFencedHandler "```" `mappend` codeFencedHandler "~~~"
+        }
+
+-- | Helper for creating a 'FHRaw'.
+--
+-- Since 0.1.2
+codeFencedHandler :: Text -- ^ Delimiter
+                  -> Map Text (Text -> FencedHandler)
+codeFencedHandler key = singleton key $ \lang -> FHRaw $
+    return . BlockCode (if T.null lang then Nothing else Just lang)
+
+-- | Helper for creating a 'FHParsed'.
+--
+-- Note that the start and end parameters take a @Text@ parameter; this is the
+-- text following the delimiter. For example, with the markdown:
+--
+-- > @@@ foo
+--
+-- @foo@ would be passed to start and end.
+--
+-- Since 0.1.2
+htmlFencedHandler :: Text -- ^ Delimiter
+                  -> (Text -> Text) -- ^ start HTML
+                  -> (Text -> Text) -- ^ end HTML
+                  -> Map Text (Text -> FencedHandler)
+htmlFencedHandler key start end = singleton key $ \lang -> FHParsed $ \blocks ->
+      BlockHtml (start lang)
+    : blocks
+   ++ [BlockHtml $ end lang]
+
+data ListType = Ordered | Unordered
+  deriving (Show, Eq)
+
+data Block inline
+    = BlockPara inline
+    | BlockList ListType (Either inline [Block inline])
+    | BlockCode (Maybe Text) Text
+    | BlockQuote [Block inline]
+    | BlockHtml Text
+    | BlockRule
+    | BlockHeading Int inline
+    | BlockReference Text Text
+    | BlockPlainText inline
+  deriving (Show, Eq)
+
+instance Functor Block where
+    fmap f (BlockPara i) = BlockPara (f i)
+    fmap f (BlockList lt (Left i)) = BlockList lt $ Left $ f i
+    fmap f (BlockList lt (Right bs)) = BlockList lt $ Right $ map (fmap f) bs
+    fmap _ (BlockCode a b) = BlockCode a b
+    fmap f (BlockQuote bs) = BlockQuote $ map (fmap f) bs
+    fmap _ (BlockHtml t) = BlockHtml t
+    fmap _ BlockRule = BlockRule
+    fmap f (BlockHeading level i) = BlockHeading level (f i)
+    fmap _ (BlockReference x y) = BlockReference x y
+    fmap f (BlockPlainText x) = BlockPlainText (f x)
diff --git a/markdown-kate.cabal b/markdown-kate.cabal
new file mode 100644
--- /dev/null
+++ b/markdown-kate.cabal
@@ -0,0 +1,57 @@
+Name:                markdown-kate
+Version:             0.1.2.1
+Synopsis:            Convert Markdown to HTML, with XSS protection
+Description:         This library leverages existing high-performance libraries (attoparsec, blaze-html, text, and conduit), and should integrate well with existing codebases.
+Homepage:            https://github.com/joelteon/markdown-kate
+License:             BSD3
+License-file:        LICENSE
+Author:              Michael Snoyman
+Maintainer:          joel@outright.com
+Category:            Web
+Build-type:          Simple
+Extra-source-files:  test/examples/*.html
+                   , test/examples/*.md
+                   , test/Tests/*.html
+                   , test/Tests/*.text
+Cabal-version:       >=1.8
+
+Library
+  Exposed-modules:     Text.Markdown
+                       Text.Markdown.Block
+                       Text.Markdown.Inline
+  other-modules:       Text.Markdown.Types
+  Build-depends:       base                   >= 4       && < 5
+                     , blaze-html             >= 0.4
+                     , attoparsec             >= 0.10
+                     , attoparsec-conduit     >= 0.5
+                     , transformers           >= 0.2.2
+                     , conduit                >= 0.5.2.1
+                     , text
+                     , data-default           >= 0.3
+                     , xss-sanitize           >= 0.3.3
+                     , containers
+                     , highlighting-kate
+  ghc-options:       -Wall
+
+test-suite test
+    hs-source-dirs: test
+    main-is: main.hs
+    other-modules: Block
+                   Inline
+    type: exitcode-stdio-1.0
+
+    ghc-options:   -Wall
+    build-depends: markdown
+                 , base             >= 4       && < 5
+                 , hspec            >= 1.3
+                 , blaze-html
+                 , text
+                 , system-fileio
+                 , system-filepath
+                 , transformers
+                 , conduit
+                 , containers
+
+source-repository head
+  type:     git
+  location: git://github.com/joelteon/markdown-kate.git
diff --git a/test/Block.hs b/test/Block.hs
new file mode 100644
--- /dev/null
+++ b/test/Block.hs
@@ -0,0 +1,86 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Block
+    ( blockSpecs
+    ) where
+import Test.Hspec
+import Data.Text (Text)
+import Data.Conduit
+import qualified Data.Conduit.List as CL
+import Text.Markdown (def)
+import Text.Markdown.Block
+import Data.Functor.Identity (runIdentity)
+
+check :: Text -> [Block Text] -> Expectation
+check md blocks = runIdentity (yield md $$ toBlocks def =$ CL.consume) `shouldBe` blocks
+
+blockSpecs :: Spec
+blockSpecs = do
+    describe "tilde code" $ do
+        it "simple" $ check
+            "~~~haskell\nfoo\n\nbar\n~~~"
+            [BlockCode (Just "haskell") "foo\n\nbar"]
+        it "no lang" $ check
+            "~~~\nfoo\n\nbar\n~~~"
+            [BlockCode Nothing "foo\n\nbar"]
+        it "no close" $ check
+            "~~~\nfoo\n\nbar\n"
+            [BlockPara " ~~~\nfoo", BlockPara "bar"]
+    describe "list" $ do
+        it "simple" $ check
+            "* foo\n\n*    bar\n\n"
+            [ BlockList Unordered (Right [BlockPara "foo"])
+            , BlockList Unordered (Right [BlockPara "bar"])
+            ]
+        it "nested" $ check
+            "* foo\n* \n    1. bar\n    2. baz"
+            [ BlockList Unordered (Left "foo")
+            , BlockList Unordered (Right
+                [ BlockList Ordered $ Left "bar"
+                , BlockList Ordered $ Left "baz"
+                ])
+            ]
+        it "with blank" $ check
+            "*   foo\n\n    bar\n\n* baz"
+            [ BlockList Unordered $ Right
+                [ BlockPara "foo"
+                , BlockPara "bar"
+                ]
+            , BlockList Unordered $ Right
+                [ BlockPara "baz"
+                ]
+            ]
+    describe "blockquote" $ do
+        it "simple" $ check
+            "> foo\n>\n> * bar"
+            [ BlockQuote
+                [ BlockPara "foo"
+                , BlockList Unordered $ Left "bar"
+                ]
+            ]
+        it "blank" $ check
+            "> foo\n\n> * bar"
+            [ BlockQuote [BlockPara "foo"]
+            , BlockQuote [BlockList Unordered $ Left "bar"]
+            ]
+    describe "indented code" $ do
+        it "simple" $ check
+            "    foo\n    bar\n"
+            [ BlockCode Nothing "foo\nbar"
+            ]
+        it "blank" $ check
+            "    foo\n\n    bar\n"
+            [ BlockCode Nothing "foo\n\nbar"
+            ]
+        it "extra space" $ check
+            "    foo\n\n     bar\n"
+            [ BlockCode Nothing "foo\n\n bar"
+            ]
+    describe "html" $ do
+        it "simple" $ check
+            "<p>Hello world!</p>"
+            [ BlockHtml "<p>Hello world!</p>"
+            ]
+        it "multiline" $ check
+            "<p>Hello world!\n</p>"
+            [ BlockHtml "<p>Hello world!\n</p>"
+            ]
diff --git a/test/Inline.hs b/test/Inline.hs
new file mode 100644
--- /dev/null
+++ b/test/Inline.hs
@@ -0,0 +1,75 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Inline
+    ( inlineSpecs
+    ) where
+
+import Test.Hspec
+import Text.Markdown.Inline
+import Data.Text (Text)
+import Data.Monoid (mempty)
+
+check :: Text -> [Inline] -> Expectation
+check md ins = toInline mempty md `shouldBe` ins
+
+inlineSpecs :: Spec
+inlineSpecs = do
+    describe "raw text" $ do
+        it "simple"
+            $ check "raw text" [InlineText "raw text"]
+        it "multiline"
+            $ check "raw\ntext" [InlineText "raw\ntext"]
+    describe "italic" $ do
+        it "asterisk"
+            $ check "raw *text*" [InlineText "raw ", InlineItalic [InlineText "text"]]
+        it "underline"
+            $ check "raw _text_" [InlineText "raw ", InlineItalic [InlineText "text"]]
+        it "multiline"
+            $ check "*raw\ntext*" [InlineItalic [InlineText "raw\ntext"]]
+        it "mismatched"
+            $ check "*foo* *bar" [InlineItalic [InlineText "foo"], InlineText " *bar"]
+    describe "bold" $ do
+        it "asterisk"
+            $ check "raw **text**" [InlineText "raw ", InlineBold [InlineText "text"]]
+        it "underline"
+            $ check "raw __text__" [InlineText "raw ", InlineBold [InlineText "text"]]
+        it "multiline"
+            $ check "**raw\ntext**" [InlineBold [InlineText "raw\ntext"]]
+        it "mismatched"
+            $ check "**foo** *bar" [InlineBold [InlineText "foo"], InlineText " *bar"]
+    describe "nested" $ do
+        it "bold inside italic"
+            $ check "*i __ib__ i*" [InlineItalic [InlineText "i ", InlineBold [InlineText "ib"], InlineText " i"]]
+        it "bold inside italic swap"
+            $ check "_i **ib** i_" [InlineItalic [InlineText "i ", InlineBold [InlineText "ib"], InlineText " i"]]
+        it "italic inside bold"
+            $ check "**b _ib_ b**" [InlineBold [InlineText "b ", InlineItalic [InlineText "ib"], InlineText " b"]]
+        it "italic inside bold swap"
+            $ check "__b *ib* b__" [InlineBold [InlineText "b ", InlineItalic [InlineText "ib"], InlineText " b"]]
+    describe "code" $ do
+        it "takes all characters"
+            $ check "`foo*__*bar` baz`"
+                [ InlineCode "foo*__*bar"
+                , InlineText " baz`"
+                ]
+    describe "escaping" $ do
+        it "asterisk"
+            $ check "\\*foo*\\\\" [InlineText "*foo*\\"]
+    describe "links" $ do
+        it "simple" $ check "[bar](foo)" [InlineLink "foo" Nothing [InlineText "bar"]]
+        it "title" $ check
+            "[bar](foo \"baz\")"
+            [InlineLink "foo" (Just "baz") [InlineText "bar"]]
+            {-
+        it "escaped href" $ check
+            "<p><a href=\"foo)\" title=\"baz\">bar</a></p>"
+            "[bar](foo\\) \"baz\")"
+        it "escaped title" $ check
+            "<p><a href=\"foo)\" title=\"baz&quot;\">bar</a></p>"
+            "[bar](foo\\) \"baz\\\"\")"
+        it "inside a paragraph" $ check
+            "<p>Hello <a href=\"foo\">bar</a> World</p>"
+            "Hello [bar](foo) World"
+        it "not a link" $ check
+            "<p>Not a [ link</p>"
+            "Not a [ link"
+            -}
diff --git a/test/Tests/Amps and angle encoding.html b/test/Tests/Amps and angle encoding.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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&#39;s a <a href="http://example.com/?foo=1&amp;bar=2">link</a> with an ampersand in the URL.</p>
+
+<p>Here&#39;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&#39;s an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
+
+<p>Here&#39;s an inline <a href="/script?foo=1&amp;bar=2">link</a>.</p>
diff --git a/test/Tests/Amps and angle encoding.text b/test/Tests/Amps and angle encoding.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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"
diff --git a/test/Tests/Auto links.html b/test/Tests/Auto links.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Auto links.text b/test/Tests/Auto links.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/>
diff --git a/test/Tests/Backslash escapes.html b/test/Tests/Backslash escapes.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Backslash escapes.html
@@ -0,0 +1,118 @@
+<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>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: \-
+</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>These should get escaped, even though they&#39;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/test/Tests/Backslash escapes.text b/test/Tests/Backslash escapes.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Backslash escapes.text
@@ -0,0 +1,120 @@
+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: \-
+
+
+
+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: \-
+
+
+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: `\-`
+
+
+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/test/Tests/Blockquotes with code blocks.html b/test/Tests/Blockquotes with code blocks.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Blockquotes with code blocks.text b/test/Tests/Blockquotes with code blocks.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Blockquotes with code blocks.text
@@ -0,0 +1,11 @@
+> Example:
+> 
+>     sub status {
+>         print "working";
+>     }
+> 
+> Or:
+> 
+>     sub status {
+>         return "working";
+>     }
diff --git a/test/Tests/Code Blocks.html b/test/Tests/Code Blocks.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Code Blocks.text b/test/Tests/Code Blocks.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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
diff --git a/test/Tests/Code Spans.html b/test/Tests/Code Spans.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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&#39;s how you put <code>`backticks`</code> in a code span.</p>
diff --git a/test/Tests/Code Spans.text b/test/Tests/Code Spans.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Code Spans.text
@@ -0,0 +1,5 @@
+`<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/test/Tests/Hard-wrapped paragraphs with list-like lines.html b/test/Tests/Hard-wrapped paragraphs with list-like lines.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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&#39;s one with a bullet.
+* criminey.</p>
diff --git a/test/Tests/Hard-wrapped paragraphs with list-like lines.text b/test/Tests/Hard-wrapped paragraphs with list-like lines.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Horizontal rules.html b/test/Tests/Horizontal rules.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Horizontal rules.text b/test/Tests/Horizontal rules.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Horizontal rules.text
@@ -0,0 +1,67 @@
+Dashes:
+
+---
+
+ ---
+ 
+  ---
+
+   ---
+
+	---
+
+- - -
+
+ - - -
+ 
+  - - -
+
+   - - -
+
+	- - -
+
+
+Asterisks:
+
+***
+
+ ***
+ 
+  ***
+
+   ***
+
+	***
+
+* * *
+
+ * * *
+ 
+  * * *
+
+   * * *
+
+	* * *
+
+
+Underscores:
+
+___
+
+ ___
+ 
+  ___
+
+   ___
+
+    ___
+
+_ _ _
+
+ _ _ _
+ 
+  _ _ _
+
+   _ _ _
+
+    _ _ _
diff --git a/test/Tests/Images.html b/test/Tests/Images.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Images.html
@@ -0,0 +1,21 @@
+<p><img src="/path/to/img.jpg" alt="Alt text"></p>
+
+<p><img src="/path/to/img.jpg" alt="Alt text" title="Optional title"></p>
+
+<p>Inline within a paragraph: <a href="/url/">alt text</a>.</p>
+
+<p><img src="/url/" alt="alt text" title="title preceded by two spaces"></p>
+
+<p><img src="/url/" alt="alt text" title="title has spaces afterward"></p>
+
+<p><img src="/url/" alt="alt text"></p>
+
+<p><img src="/url/" alt="alt text" title="with a title">.</p>
+
+<p><img src="" alt="Empty"></p>
+
+<p><img src="http://example.com/(parens).jpg" alt="this is a stupid URL"></p>
+
+<p><img src="/url/" alt="alt text"></p>
+
+<p><img src="/url/" alt="alt text" title="Title here"></p>
diff --git a/test/Tests/Images.text b/test/Tests/Images.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Images.text
@@ -0,0 +1,26 @@
+![Alt text](/path/to/img.jpg)
+
+![Alt text](/path/to/img.jpg "Optional title")
+
+Inline within a paragraph: [alt text](/url/).
+
+![alt text](/url/  "title preceded by two spaces")
+
+![alt text](/url/  "title has spaces afterward"  )
+
+![alt text](</url/>)
+
+![alt text](</url/> "with a title").
+
+![Empty]()
+
+![this is a stupid URL](http://example.com/(parens).jpg)
+
+
+![alt text][foo]
+
+  [foo]: /url/
+
+![alt text][bar]
+
+  [bar]: /url/ "Title here"
diff --git a/test/Tests/Inline HTML (Advanced).html b/test/Tests/Inline HTML (Advanced).html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Inline HTML (Advanced).html
@@ -0,0 +1,30 @@
+<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>
+
+<p>And with attributes:</p>
+
+<div>
+    <div id="foo">
+    </div>
+</div>
+
+<p>This was broken in 1.0.2b7:</p>
+
+<div class="inlinepage">
+<div class="toggleableend">
+foo
+</div>
+</div>
diff --git a/test/Tests/Inline HTML (Advanced).text b/test/Tests/Inline HTML (Advanced).text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Inline HTML (Advanced).text
@@ -0,0 +1,30 @@
+Simple block on one line:
+
+<div>foo</div>
+
+And nested without indentation:
+
+<div>
+<div>
+<div>
+foo
+</div>
+<div style=">"/>
+</div>
+<div>bar</div>
+</div>
+
+And with attributes:
+
+<div>
+	<div id="foo">
+	</div>
+</div>
+
+This was broken in 1.0.2b7:
+
+<div class="inlinepage">
+<div class="toggleableend">
+foo
+</div>
+</div>
diff --git a/test/Tests/Inline HTML (Simple).html b/test/Tests/Inline HTML (Simple).html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Inline HTML (Simple).html
@@ -0,0 +1,72 @@
+<p>Here&#39;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&#39;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/test/Tests/Inline HTML (Simple).text b/test/Tests/Inline HTML (Simple).text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Inline HTML comments.html b/test/Tests/Inline HTML comments.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Inline HTML comments.text b/test/Tests/Inline HTML comments.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Links, inline style.html b/test/Tests/Links, inline style.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Links, inline style.html
@@ -0,0 +1,23 @@
+<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><a href="/url/">URL wrapped in angle brackets</a>.</p>
+
+<p><a href="/url/" title="Here&#39;s the title">URL w/ angle brackets + title</a>.</p>
+
+<p><a href="">Empty</a>.</p>
+
+<p><a href="http://en.wikipedia.org/wiki/WIMP_(computing)">With parens in the URL</a></p>
+
+<p>(With outer parens and <a href="/foo(bar)">parens in url</a>)</p>
+
+<p><a href="/foo(bar)" title="and a title">With parens in the URL</a></p>
+
+<p>(With outer parens and <a href="/foo(bar)" title="and a title">parens in url</a>)</p>
diff --git a/test/Tests/Links, inline style.text b/test/Tests/Links, inline style.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Links, inline style.text
@@ -0,0 +1,24 @@
+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"  ).
+
+[URL wrapped in angle brackets](</url/>).
+
+[URL w/ angle brackets + title](</url/> "Here's the title").
+
+[Empty]().
+
+[With parens in the URL](http://en.wikipedia.org/wiki/WIMP_(computing))
+
+(With outer parens and [parens in url](/foo(bar)))
+
+
+[With parens in the URL](/foo(bar) "and a title")
+
+(With outer parens and [parens in url](/foo(bar) "and a title"))
diff --git a/test/Tests/Links, reference style.html b/test/Tests/Links, reference style.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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&#39;s one where the <a href="/url/">link
+breaks</a> across lines.</p>
+
+<p>Here&#39;s another where the <a href="/url/">link 
+breaks</a> across lines, but with a line-ending space.</p>
diff --git a/test/Tests/Links, reference style.text b/test/Tests/Links, reference style.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Links, shortcut references.html b/test/Tests/Links, shortcut references.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Links, shortcut references.text b/test/Tests/Links, shortcut references.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Literal quotes in titles.html b/test/Tests/Literal quotes in titles.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Literal quotes in titles.text b/test/Tests/Literal quotes in titles.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Markdown Documentation - Basics.html b/test/Tests/Markdown Documentation - Basics.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/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
+"underlining" 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="http://example.com/"&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/ "With a Title").
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;This is an &lt;a href="http://example.com/" title="With a Title"&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/        "Google"
+[2]: http://search.yahoo.com/  "Yahoo Search"
+[3]: http://search.msn.com/    "MSN Search"
+</code></pre>
+
+<p>Output:</p>
+
+<pre><code>&lt;p&gt;I get 10 times more traffic from &lt;a href="http://google.com/"
+title="Google"&gt;Google&lt;/a&gt; than from &lt;a href="http://search.yahoo.com/"
+title="Yahoo Search"&gt;Yahoo&lt;/a&gt; or &lt;a href="http://search.msn.com/"
+title="MSN Search"&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="http://www.nytimes.com/"&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 "Title")
+</code></pre>
+
+<p>Reference-style:</p>
+
+<pre><code>![alt text][id]
+
+[id]: /path/to/img.jpg "Title"
+</code></pre>
+
+<p>Both of the above examples produce the same output:</p>
+
+<pre><code>&lt;img src="/path/to/img.jpg" alt="alt text" title="Title" /&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/test/Tests/Markdown Documentation - Syntax.html b/test/Tests/Markdown Documentation - Syntax.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Markdown Documentation - Syntax.html
@@ -0,0 +1,942 @@
+<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 "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 <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
+"every line break is a <code>&lt;br /&gt;</code>" 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 "underlined" 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 "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.) :</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("echo $input | $markdown_script");
+</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 "Foo"
+        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 "Foo"
+    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="footer"&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="footer"&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/ "Title") 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="http://example.com/" title="Title"&gt;
+an example&lt;/a&gt; inline link.&lt;/p&gt;
+
+&lt;p&gt;&lt;a href="http://example.net/"&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/  "Optional Title Here"
+</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;  "Optional Title Here"
+</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
+    "Optional Title Here"
+</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
+"Google" 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/        "Google"
+  [2]: http://search.yahoo.com/  "Yahoo Search"
+  [3]: http://search.msn.com/    "MSN Search"
+</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/        "Google"
+  [yahoo]:  http://search.yahoo.com/  "Yahoo Search"
+  [msn]:    http://search.msn.com/    "MSN Search"
+</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="http://google.com/"
+title="Google"&gt;Google&lt;/a&gt; than from
+&lt;a href="http://search.yahoo.com/" title="Yahoo Search"&gt;Yahoo&lt;/a&gt;
+or &lt;a href="http://search.msn.com/" title="MSN Search"&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/ "Google")
+than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+[MSN](http://search.msn.com/ "MSN Search").
+</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 "natural" 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 "Optional title")
+</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 "id" 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  "Optional title attribute"
+</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 "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:</p>
+
+<pre><code>&lt;http://example.com/&gt;
+</code></pre>
+
+<p>Markdown will turn this into:</p>
+
+<pre><code>&lt;a href="http://example.com/"&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="&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;"&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 "address@example.com".</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/test/Tests/Nested blockquotes.html b/test/Tests/Nested blockquotes.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Nested blockquotes.html
@@ -0,0 +1,9 @@
+<blockquote>
+<p>foo</p>
+
+<blockquote>
+<p>bar</p>
+</blockquote>
+
+<p>foo</p>
+</blockquote>
diff --git a/test/Tests/Nested blockquotes.text b/test/Tests/Nested blockquotes.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Nested blockquotes.text
@@ -0,0 +1,5 @@
+> foo
+>
+> > bar
+>
+> foo
diff --git a/test/Tests/Ordered and unordered lists.html b/test/Tests/Ordered and unordered lists.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Ordered and unordered lists.html
@@ -0,0 +1,148 @@
+<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&#39;s
+back.</p></li>
+<li><p>Item 2.</p></li>
+<li><p>Item 3.</p></li>
+</ol>
+
+<h2>Nested</h2>
+
+<ul>
+<li><p>Tab</p>
+<ul>
+<li><p>Tab</p>
+<ul>
+<li>Tab</li>
+</ul></li>
+</ul></li>
+</ul>
+
+<p>Here&#39;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/test/Tests/Strong and em together.html b/test/Tests/Strong and em together.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Strong and em together.html
@@ -0,0 +1,7 @@
+<p><b><i>This is strong and em.</i></b></p>
+
+<p>So is <b><i>this</i></b> word.</p>
+
+<p><b><i>This is strong and em.</i></b></p>
+
+<p>So is <b><i>this</i></b> word.</p>
diff --git a/test/Tests/Strong and em together.text b/test/Tests/Strong and em together.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Tabs.html b/test/Tests/Tabs.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Tabs.html
@@ -0,0 +1,25 @@
+<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/test/Tests/Tabs.text b/test/Tests/Tabs.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/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/test/Tests/Tidyness.html b/test/Tests/Tidyness.html
new file mode 100644
--- /dev/null
+++ b/test/Tests/Tidyness.html
@@ -0,0 +1,8 @@
+<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/test/Tests/Tidyness.text b/test/Tests/Tidyness.text
new file mode 100644
--- /dev/null
+++ b/test/Tests/Tidyness.text
@@ -0,0 +1,5 @@
+> A list within a blockquote:
+> 
+> *	asterisk 1
+> *	asterisk 2
+> *	asterisk 3
diff --git a/test/examples/closing-tags.html b/test/examples/closing-tags.html
new file mode 100644
--- /dev/null
+++ b/test/examples/closing-tags.html
@@ -0,0 +1,1 @@
+<ul><li><p>foo</p></li></ul>
diff --git a/test/examples/closing-tags.md b/test/examples/closing-tags.md
new file mode 100644
--- /dev/null
+++ b/test/examples/closing-tags.md
@@ -0,0 +1,1 @@
+* <p>foo</p>
diff --git a/test/examples/entities.html b/test/examples/entities.html
new file mode 100644
--- /dev/null
+++ b/test/examples/entities.html
@@ -0,0 +1,1 @@
+<p>1 &lt; 2 &amp; 2 &gt; 1, also 1 &lt; 2 &amp; 2 &gt; 1   ý &amp;#xP;</p>
diff --git a/test/examples/entities.md b/test/examples/entities.md
new file mode 100644
--- /dev/null
+++ b/test/examples/entities.md
@@ -0,0 +1,1 @@
+1 < 2 & 2 > 1, also 1 &lt; 2 &amp; 2 &gt; 1 &#160; &#xfd; &#xP;
diff --git a/test/examples/fence-whitespace.html b/test/examples/fence-whitespace.html
new file mode 100644
--- /dev/null
+++ b/test/examples/fence-whitespace.html
@@ -0,0 +1,1 @@
+<p>foo</p><pre><code>bar</code></pre>
diff --git a/test/examples/fence-whitespace.md b/test/examples/fence-whitespace.md
new file mode 100644
--- /dev/null
+++ b/test/examples/fence-whitespace.md
@@ -0,0 +1,4 @@
+foo
+```
+bar
+```
diff --git a/test/examples/lazy.html b/test/examples/lazy.html
new file mode 100644
--- /dev/null
+++ b/test/examples/lazy.html
@@ -0,0 +1,3 @@
+<blockquote><p>this is
+lazy</p></blockquote><ol><li>This is
+a list</li><li>Another item</li></ol>
diff --git a/test/examples/lazy.md b/test/examples/lazy.md
new file mode 100644
--- /dev/null
+++ b/test/examples/lazy.md
@@ -0,0 +1,6 @@
+> this is
+lazy
+
+1.  This is
+a list
+2.  Another item
diff --git a/test/examples/list-blocks.html b/test/examples/list-blocks.html
new file mode 100644
--- /dev/null
+++ b/test/examples/list-blocks.html
@@ -0,0 +1,1 @@
+<ul><li><p>This is a paragraph.</p><p>Another paragraph.</p></li><li><p>Non-paragraph.</p></li><li><p>Item.</p><ul><li>Sublist item.</li><li><ol><li>Item 1</li><li>Item 2</li></ol></li></ul></li></ul>
diff --git a/test/examples/list-blocks.md b/test/examples/list-blocks.md
new file mode 100644
--- /dev/null
+++ b/test/examples/list-blocks.md
@@ -0,0 +1,12 @@
+*   This is a paragraph.
+
+    Another paragraph.
+
+* Non-paragraph.
+
+*   Item.
+
+    * Sublist item.
+    * 
+        1. Item 1
+        2. Item 2
diff --git a/test/examples/lists-code.html b/test/examples/lists-code.html
new file mode 100644
--- /dev/null
+++ b/test/examples/lists-code.html
@@ -0,0 +1,2 @@
+<ol><li>hello
+world</li><li><p>hello</p><pre><code class="haskell">data Foo</code></pre></li></ol>
diff --git a/test/examples/lists-code.md b/test/examples/lists-code.md
new file mode 100644
--- /dev/null
+++ b/test/examples/lists-code.md
@@ -0,0 +1,7 @@
+1. hello
+   world
+2.    hello
+
+      ```haskell
+      data Foo
+      ```
diff --git a/test/examples/multiline-paragraphs.html b/test/examples/multiline-paragraphs.html
new file mode 100644
--- /dev/null
+++ b/test/examples/multiline-paragraphs.html
@@ -0,0 +1,5 @@
+<p>This is a multiline
+paragraph.</p><ul><li><p>Multiline paragraph
+in a list.</p></li><li><p>The purpose of classy prelude is <i>not</i> to encourage writing polymorphic
+code based on the typeclasses provided. Though it's certainly possible to
+write code such as:</p></li></ul>
diff --git a/test/examples/multiline-paragraphs.md b/test/examples/multiline-paragraphs.md
new file mode 100644
--- /dev/null
+++ b/test/examples/multiline-paragraphs.md
@@ -0,0 +1,9 @@
+This is a multiline
+paragraph.
+
+*    Multiline paragraph
+     in a list.
+
+*   The purpose of classy prelude is *not* to encourage writing polymorphic
+    code based on the typeclasses provided. Though it's certainly possible to
+    write code such as:
diff --git a/test/examples/sublists.html b/test/examples/sublists.html
new file mode 100644
--- /dev/null
+++ b/test/examples/sublists.html
@@ -0,0 +1,1 @@
+<ol><li>No encounters</li><li>Encounters<ol><li>First kind</li><li>Second kind</li></ol></li></ol>
diff --git a/test/examples/sublists.md b/test/examples/sublists.md
new file mode 100644
--- /dev/null
+++ b/test/examples/sublists.md
@@ -0,0 +1,4 @@
+1.  No encounters
+2.  Encounters
+    1. First kind
+    2. Second kind
diff --git a/test/examples/tilde-code.html b/test/examples/tilde-code.html
new file mode 100644
--- /dev/null
+++ b/test/examples/tilde-code.html
@@ -0,0 +1,4 @@
+<pre><code class="haskell">foo
+bar
+
+baz</code></pre>
diff --git a/test/examples/tilde-code.md b/test/examples/tilde-code.md
new file mode 100644
--- /dev/null
+++ b/test/examples/tilde-code.md
@@ -0,0 +1,6 @@
+~~~haskell
+foo
+bar
+
+baz
+~~~
diff --git a/test/main.hs b/test/main.hs
new file mode 100644
--- /dev/null
+++ b/test/main.hs
@@ -0,0 +1,226 @@
+{-# LANGUAGE OverloadedStrings #-}
+import Test.Hspec
+import Text.Markdown
+import Data.Text.Lazy (Text, unpack, snoc, fromStrict)
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import Text.Blaze.Html.Renderer.Text (renderHtml)
+import Control.Monad (forM_)
+import qualified Data.Set as Set
+import qualified Data.Map as Map
+
+import qualified Filesystem.Path.CurrentOS as F
+import qualified Filesystem as F
+
+import Block
+import Inline
+
+check :: Text -> Text -> Expectation
+check html md = renderHtml (markdown def md) `shouldBe` html
+
+checkSet :: MarkdownSettings -> Text -> Text -> Expectation
+checkSet set html md = renderHtml (markdown set md) `shouldBe` html
+
+check' :: Text -> Text -> Expectation
+check' html md = renderHtml (markdown def { msXssProtect = False } md) `shouldBe` html
+
+checkNoNL :: Text -> Text -> Expectation
+checkNoNL html md =
+    f (renderHtml $ markdown def { msXssProtect = False } md) `shouldBe` f html
+  where
+    f = TL.filter (/= '\n')
+
+-- FIXME add quickcheck: all input is valid
+
+main :: IO ()
+main = do
+  examples <- getExamples
+  gruber <- getGruber
+  hspec $ do
+    describe "block" blockSpecs
+    describe "inline" inlineSpecs
+    describe "paragraphs" $ do
+        it "simple"
+            $ check "<p>Hello World!</p>" "Hello World!"
+        it "multiline"
+            $ check "<p>Hello\nWorld!</p>" "Hello\nWorld!"
+        it "multiple"
+            $ check "<p>Hello</p><p>World!</p>" "Hello\n\nWorld!"
+    describe "italics" $ do
+        it "simple"
+            $ check "<p><i>foo</i></p>" "*foo*"
+        it "hanging"
+            $ check "<p><i>foo</i> *</p>" "*foo* *"
+        it "two"
+            $ check "<p><i>foo</i> <i>bar</i></p>" "*foo* *bar*"
+    describe "italics under" $ do
+        it "simple"
+            $ check "<p><i>foo</i></p>" "_foo_"
+        it "hanging"
+            $ check "<p><i>foo</i> _</p>" "_foo_ _"
+        it "two"
+            $ check "<p><i>foo</i> <i>bar</i></p>" "_foo_ _bar_"
+    describe "bold" $ do
+        it "simple"
+            $ check "<p><b>foo</b></p>" "**foo**"
+        it "hanging"
+            $ check "<p><b>foo</b> **</p>" "**foo** **"
+        it "two"
+            $ check "<p><b>foo</b> <b>bar</b></p>" "**foo** **bar**"
+    describe "bold under" $ do
+        it "simple"
+            $ check "<p><b>foo</b></p>" "__foo__"
+        it "hanging"
+            $ check "<p><b>foo</b> __</p>" "__foo__ __"
+        it "two"
+            $ check "<p><b>foo</b> <b>bar</b></p>" "__foo__ __bar__"
+    describe "html" $ do
+        it "simple"
+            $ check "<div>Hello</div>" "<div>Hello</div>"
+        it "dangerous"
+            $ check "<div>Hello</div>" "<div onclick='alert(foo)'>Hello</div>"
+        it "dangerous and allowed"
+            $ check' "<div onclick='alert(foo)'>Hello</div>" "<div onclick='alert(foo)'>Hello</div>"
+
+        let ml = "<div>foo\nbar\nbaz</div>"
+        it "multiline" $ check ml ml
+
+        let close = "<div>foo\nbar\nbaz"
+        it "autoclose" $ check ml close
+
+        let close2 = "<div>foo\nbar\nbaz\n\nparagraph"
+        it "autoclose 2"
+            $ check "<div>foo\nbar\nbaz<p>paragraph</p></div>" close2
+    describe "inline code" $ do
+        it "simple"
+            $ check "<p>foo <code>bar</code> baz</p>" "foo `bar` baz"
+    describe "code block" $ do
+        it "simple"
+            $ check
+                "<pre><code>foo\n bar\nbaz</code></pre>"
+                "    foo\n     bar\n    baz"
+    describe "escaping" $ do
+        it "everything"
+            $ check
+                "<p>*foo_bar<i>baz</i>\\`bin</p>"
+                "\\*foo\\_bar_baz_\\\\\\`bin"
+    describe "bullets" $ do
+        it "simple"
+            $ check
+                "<ul><li>foo</li><li>bar</li><li>baz</li></ul>"
+                "* foo\n* bar\n* baz\n"
+    describe "numbers" $ do
+        it "simple"
+            $ check
+                "<ol><li>foo</li><li>bar</li><li>baz</li></ol>"
+                "5. foo\n2. bar\n1. baz\n"
+    describe "headings" $ do
+        it "hashes"
+            $ check
+                "<h1>foo</h1><h2>bar</h2><h3>baz</h3>"
+                "# foo\n\n##     bar\n\n###baz"
+        it "trailing hashes"
+            $ check
+                "<h1>foo</h1>"
+                "# foo    ####"
+        it "underline"
+            $ check
+                "<h1>foo</h1><h2>bar</h2>"
+                "foo\n=============\n\nbar\n----------------\n"
+    describe "blockquotes" $ do
+        it "simple"
+            $ check
+                "<blockquote><p>foo</p><pre><code>bar</code></pre></blockquote>"
+                "> foo\n>\n>     bar"
+    describe "links" $ do
+        it "simple" $ check "<p><a href=\"foo\">bar</a></p>" "[bar](foo)"
+        it "title" $ check
+            "<p><a href=\"foo\" title=\"baz\">bar</a></p>"
+            "[bar](foo \"baz\")"
+        it "escaped href" $ check
+            "<p><a href=\"foo)\" title=\"baz\">bar</a></p>"
+            "[bar](foo\\) \"baz\")"
+        it "escaped title" $ check
+            "<p><a href=\"foo)\" title=\"baz&quot;\">bar</a></p>"
+            "[bar](foo\\) \"baz\\\"\")"
+        it "inside a paragraph" $ check
+            "<p>Hello <a href=\"foo\">bar</a> World</p>"
+            "Hello [bar](foo) World"
+        it "not a link" $ check
+            "<p>Not a [ link</p>"
+            "Not a [ link"
+
+    {-
+    describe "github links" $ do
+        it "simple" $ check "<p><a href=\"foo\">bar</a></p>" "[[bar|foo]]"
+        it "no link text" $ check "<p><a href=\"foo\">foo</a></p>" "[[foo]]"
+        it "escaping" $ check "<p><a href=\"foo-baz-bin\">bar</a></p>" "[[bar|foo/baz bin]]"
+        it "inside a list" $ check "<ul><li><a href=\"foo\">foo</a></li></ul>" "* [[foo]]"
+    -}
+
+    describe "images" $ do
+        it "simple" $ check 
+            "<p><img src=\"http://link.to/image.jpg\" alt=\"foo\"></p>"
+            "![foo](http://link.to/image.jpg)"
+        it "title" $ check
+            "<p><img src=\"http://link.to/image.jpg\" alt=\"foo\" title=\"bar\"></p>"
+            "![foo](http://link.to/image.jpg \"bar\")"
+        it "inside a paragraph" $ check
+            "<p>Hello <img src=\"http://link.to/image.jpg\" alt=\"foo\"> World</p>"
+            "Hello ![foo](http://link.to/image.jpg) World"
+        it "not an image" $ check
+            "<p>Not an ![ image</p>"
+            "Not an ![ image"
+
+    describe "rules" $ do
+        let options = concatMap (\t -> [t, snoc t '\n'])
+                [ "* * *"
+                , "***"
+                , "*****"
+                , "- - -"
+                , "---------------------------------------"
+                , "----------------------------------"
+                ]
+        forM_ options $ \o -> it (unpack o) $ check "<hr>" o
+
+    describe "html" $ do
+        it "inline" $ check "<p>foo<br>bar</p>" "foo<br>bar"
+        it "inline xss" $ check "<p>foo<br>bar</p>" "foo<br onclick='evil'>bar"
+        it "block" $ check "<div>hello world</div>" "<div>hello world</div>"
+        it "block xss" $ check "alert('evil')" "<script>alert('evil')</script>"
+        it "should be escaped" $ check "<p>1 &lt; 2</p>" "1 < 2"
+        it "standalone" $ checkSet
+            def { msStandaloneHtml = Set.fromList ["<hidden>", "</hidden>"], msXssProtect = False }
+            "<hidden><pre><code class=\"haskell\">foo\nbar</code></pre></hidden>"
+            "<hidden>\n```haskell\nfoo\nbar\n```\n</hidden>\n"
+    describe "fencing" $ do
+        it "custom fencing" $ checkSet
+            def
+                { msFencedHandlers = Map.union
+                    (htmlFencedHandler "@@@" (\clazz -> T.concat ["<article class=\"", clazz, "\">"]) (const "</article>"))
+                    (msFencedHandlers def)
+                }
+            "<article class=\"someclass\"><p>foo</p><blockquote><p>bar</p></blockquote></article>"
+            "@@@ someclass\nfoo\n\n> bar\n@@@"
+    describe "examples" $ sequence_ examples
+    describe "John Gruber's test suite" $ sequence_ gruber
+
+getExamples :: IO [Spec]
+getExamples = do
+    files <- F.listDirectory "test/examples"
+    mapM go $ filter (flip F.hasExtension "md") files
+  where
+    go fp = do
+        input <- F.readTextFile fp
+        output <- F.readTextFile $ F.replaceExtension fp "html"
+        return $ it (F.encodeString $ F.basename fp) $ check (fromStrict $ T.strip output) (fromStrict input)
+
+getGruber :: IO [Spec]
+getGruber = do
+    files <- F.listDirectory "test/Tests"
+    mapM go $ filter (flip F.hasExtension "text") files
+  where
+    go fp = do
+        input <- F.readTextFile fp
+        output <- F.readTextFile $ F.replaceExtension fp "html"
+        return $ it (F.encodeString $ F.basename fp) $ checkNoNL (fromStrict $ T.strip output) (fromStrict input)
