diff --git a/BlogLiterately.cabal b/BlogLiterately.cabal
--- a/BlogLiterately.cabal
+++ b/BlogLiterately.cabal
@@ -1,5 +1,5 @@
 Name:           BlogLiterately
-Version:        0.8.4.3
+Version:        0.8.5
 Synopsis:       A tool for posting Haskelly articles to blogs
 Description:    Write blog posts in Markdown format, then use BlogLiterately
                 to do syntax highlighting, format ghci sessions, and upload
@@ -26,7 +26,7 @@
 Maintainer:     Brent Yorgey <byorgey@gmail.com>
 Stability:      experimental
 Build-Type:     Simple
-Tested-With:    GHC ==7.6.3, GHC ==7.8.4, GHC ==7.10.3, GHC ==8.0.1
+Tested-With:    GHC ==7.8.4, GHC ==7.10.3, GHC ==8.0.2, GHC ==8.2.1
 Extra-Source-Files: CHANGES.md
                     README.markdown
                     doc/BlogLiteratelyDoc.lhs
@@ -39,7 +39,7 @@
   location: git://github.com/byorgey/BlogLiterately.git
 
 Library
-  Build-Depends:   base >= 4.0 && < 4.10,
+  Build-Depends:   base >= 4.0 && < 4.11,
                    process,
                    filepath,
                    directory,
@@ -47,6 +47,7 @@
                    containers,
                    bool-extras,
                    mtl,
+                   text >= 1.2 && < 1.3,
                    temporary >= 1.1 && < 1.3,
                    strict >= 0.3 && < 0.4,
                    split >= 0.1.4 && < 0.3,
@@ -54,12 +55,12 @@
                    parsec >= 3 && < 3.2,
                    HaXml >= 1.22 && < 1.26,
                    hscolour >= 1.20 && < 1.25,
-                   blaze-html >= 0.5 && < 0.9,
+                   blaze-html >= 0.5 && < 0.10,
                    cmdargs >= 0.9.5 && < 0.11,
                    haxr >= 3000.11 && < 3000.12,
-                   pandoc >= 1.19 && < 1.20,
-                   pandoc-types >= 1.16 && < 1.18,
-                   pandoc-citeproc >= 0.1.2 && < 0.11,
+                   pandoc >= 2.0 && < 2.2,
+                   pandoc-types >= 1.16 && < 1.20,
+                   pandoc-citeproc >= 0.1.2 && < 0.13,
                    highlighting-kate >= 0.5 && < 0.7,
                    data-default >= 0.5 && < 0.8,
                    lens >= 3.8 && < 4.16,
diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,9 @@
+0.8.5 (10 January 2018)
+-----------------------
+
+  - update to work with `pandoc-2.x`.  No longer builds with
+    `pandoc-1.x`.
+
 0.8.4.3 (3 December 2016)
 -------------------------
 
diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -1,3 +1,5 @@
+[![Build Status](https://travis-ci.org/byorgey/BlogLiterately.svg?branch=master)](https://travis-ci.org/byorgey/BlogLiterately)
+
 Write blog posts in Markdown format, then use BlogLiterately to do
 syntax highlighting, format ghci sessions, and upload to any blog
 supporting the [metaWeblog API (such as Wordpress)](http://codex.wordpress.org/XML-RPC_MetaWeblog_API).
diff --git a/doc/BlogLiteratelyDoc.lhs b/doc/BlogLiteratelyDoc.lhs
--- a/doc/BlogLiteratelyDoc.lhs
+++ b/doc/BlogLiteratelyDoc.lhs
@@ -79,7 +79,10 @@
 `--no-lit-haskell` command-line argument.  This makes a difference,
 for example, when processing paragraphs set off by "bird tracks"
 (*i.e.* leading `>` characters): in literate Haskell, these are code
-blocks, whereas in plain markdown they are blockquotes.
+blocks, whereas in plain markdown they are blockquotes.  In addition,
+section headings beginning with hash signs (`#`, `##`, etc.) cannot be
+used in literate Haskell mode; only section headings underlined with
+hyphens or equals signs are supported.
 
 Determining input format
 ------------------------
@@ -503,7 +506,7 @@
 String values use normal Haskell syntax for strings, surrounded by
 double quotes. Optionally, the double quotes may be omitted for
 strings which do not contain spaces, double quotes, commas, or square
-brackets. Lists use also use Haskell list syntax, with comma-separated
+brackets. Lists also use Haskell list syntax, with comma-separated
 items surrounded by square brackets, except that the square brackets
 may be omitted.  For example, `myblog.cfg` might look like this:
 
@@ -515,9 +518,9 @@
     categories = foo, bar, "some really long category"
 
 The list of options which are currently supported are: `style`,
-`wplatex`, `math`, `ghci`, `upload-images`, `categories`, `tags`,
-`blogid`, `profile`, `blog`, `user`, `password`, `title`, `postid`,
-`page`, `publish`, `xtras`.
+`lit-haskell`, `wplatex`, `math`, `ghci`, `upload-images`,
+`categories`, `tags`, `blogid`, `profile`, `blog`, `user`, `password`,
+`title`, `postid`, `page`, `publish`, `xtras`.
 
 Option blocks
 -------------
diff --git a/src/Text/BlogLiterately/Transform.hs b/src/Text/BlogLiterately/Transform.hs
--- a/src/Text/BlogLiterately/Transform.hs
+++ b/src/Text/BlogLiterately/Transform.hs
@@ -1,7 +1,7 @@
-
 {-# LANGUAGE FlexibleContexts  #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE TupleSections     #-}
 {-# LANGUAGE TypeOperators     #-}
 
 -----------------------------------------------------------------------------
@@ -68,6 +68,9 @@
 import           Data.Monoid                       (mappend)
 import           Data.Monoid                       (mempty, (<>))
 import qualified Data.Set                          as S
+import           Data.Text                         (Text)
+import qualified Data.Text                         as T
+import qualified Data.Text.Lazy                    as LT
 import           Data.Traversable                  (traverse)
 import           Network.HTTP                      (getRequest, getResponseBody,
                                                     simpleHTTP)
@@ -79,7 +82,7 @@
 import           Text.Blaze.Html.Renderer.String   (renderHtml)
 import           Text.CSL.Pandoc                   (processCites')
 import           Text.HTML.TagSoup
-import           Text.Pandoc
+import           Text.Pandoc                       hiding (openURL)
 import           Text.Pandoc.Error                 (PandocError)
 import           Text.Parsec                       (ParseError)
 
@@ -522,16 +525,16 @@
 -- | Transform a complete input document string to an HTML output
 --   string, given a list of transformation passes.
 xformDoc :: BlogLiterately -> [Transform] -> String -> IO (Either PandocError (BlogLiterately, String))
-xformDoc bl xforms =
-        fixLineEndings
-    >>> parseFile parseOpts
-    >>> traverse
-      (  runTransforms xforms bl
-      >=> (\(bl', p) -> return $ (bl', writeHtml (writeOpts bl') p) )
-      >=> _2 (return . renderHtml)
-      )
+xformDoc bl xforms = runIO .
+    (     fixLineEndings
+      >>> T.pack
+      >>> parseFile parseOpts
+      >=> (liftIO . runTransforms xforms bl)
+      >=> (\(bl', p) -> (bl',) <$> writeHtml5String (writeOpts bl') p)
+      >=> _2 (return . T.unpack)
+    )
   where
-    parseFile :: ReaderOptions -> String -> Either PandocError Pandoc
+    parseFile :: ReaderOptions -> Text -> PandocIO Pandoc
     parseFile opts =
       case bl^.format of
         Just "rst"      -> readRST      opts
@@ -545,11 +548,11 @@
 
     parseOpts = def
                 { readerExtensions =
+                    enableExtension Ext_smart $
                     case bl^.litHaskell of
                       Just False -> readerExtensions def
-                      _          -> S.insert Ext_literate_haskell
+                      _          -> enableExtension Ext_literate_haskell
                                     (readerExtensions def)
-                , readerSmart      = True
                 }
     writeOpts bl = def
                    { writerReferenceLinks = True
@@ -563,7 +566,7 @@
     mathOption opt
       | opt `isPrefixOf` "latexmathml" ||
         opt `isPrefixOf` "asciimathml" = LaTeXMathML (mathUrlMaybe opt)
-      | opt `isPrefixOf` "mathml"      = MathML (mathUrlMaybe opt)
+      | opt `isPrefixOf` "mathml"      = MathML
       | opt `isPrefixOf` "mimetex"     =
           WebTeX (mathUrl "/cgi-bin/mimetex.cgi?" opt)
       | opt `isPrefixOf` "webtex"      = WebTeX (mathUrl webTeXURL opt)
