diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Changelog
 
+- 0.8.5.0 (2020-06-29)
+    * Bump `pandoc` dependency to 2.9
+    * Switch to `goldplate` for testing
+
 - 0.8.4.3 (2020-01-21)
     * Fix Haddock syntax in some comments (contribution by Asad Saeeduddin)
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -490,6 +490,13 @@
 
 [this list]: https://hackage.haskell.org/package/highlighting-kate-0.6.3/docs/Text-Highlighting-Kate-Types.html#t:TokenType
 
+Note that in order to get syntax highlighting to work, you should annotate code
+blocks with the language, e.g. using a fenced code block:
+
+    ```ruby
+    puts "Hello, world!"
+    ```
+
 ### Pandoc Extensions
 
 Pandoc comes with a fair number of extensions on top of markdown, listed [here](https://hackage.haskell.org/package/pandoc-2.0.5/docs/Text-Pandoc-Extensions.html).
diff --git a/extra/make-man.hs b/extra/make-man.hs
--- a/extra/make-man.hs
+++ b/extra/make-man.hs
@@ -1,19 +1,20 @@
 -- | This script generates a man page for patat.
 {-# LANGUAGE OverloadedStrings #-}
-import           Control.Applicative ((<$>))
 import           Control.Exception   (throw)
 import           Control.Monad       (guard)
 import           Control.Monad.Trans (liftIO)
 import           Data.Char           (isSpace, toLower)
 import           Data.List           (isPrefixOf)
+import qualified Data.Map            as M
 import           Data.Maybe          (isJust)
 import qualified Data.Text           as T
 import qualified Data.Text.IO        as T
+import qualified Data.Time           as Time
 import qualified GHC.IO.Encoding     as Encoding
 import           Prelude
 import           System.Environment  (getEnv)
 import qualified System.IO           as IO
-import qualified Data.Time as Time
+import           Text.DocTemplates   as DT
 import qualified Text.Pandoc         as Pandoc
 
 getVersion :: IO String
@@ -54,7 +55,7 @@
 
 fromSections :: Sections -> [Pandoc.Block]
 fromSections = concatMap $ \(level, title, blocks) ->
-    Pandoc.Header level ("", [], []) [Pandoc.Str $ T.unpack title] : blocks
+    Pandoc.Header level ("", [], []) [Pandoc.Str title] : blocks
 
 reorganizeSections :: Pandoc.Pandoc -> Pandoc.Pandoc
 reorganizeSections (Pandoc.Pandoc meta0 blocks0) =
@@ -89,6 +90,9 @@
     lookupSection name sections =
         [section | section@(_, n, _) <- sections, name == n]
 
+simpleContext :: [(T.Text, T.Text)] -> DT.Context T.Text
+simpleContext = DT.toContext . M.fromList
+
 main :: IO ()
 main = Pandoc.runIOorExplode $ do
     liftIO $ Encoding.setLocaleEncoding Encoding.utf8
@@ -99,18 +103,18 @@
 
     source   <- liftIO $ T.readFile "README.md"
     pandoc0  <- Pandoc.readMarkdown readerOptions source
-    template <- Pandoc.getDefaultTemplate "man"
+    template <- Pandoc.compileDefaultTemplate "man"
 
-    version <- liftIO getVersion
-    date    <- liftIO getPrettySourceDate
+    version <- T.pack <$> liftIO getVersion
+    date    <- T.pack <$> liftIO getPrettySourceDate
 
     let writerOptions = Pandoc.def
             { Pandoc.writerTemplate   = Just template
-            , Pandoc.writerVariables  =
+            , Pandoc.writerVariables  = simpleContext
                 [ ("author",  "Jasper Van der Jeugt")
                 , ("title",   "patat manual")
                 , ("date",    date)
-                , ("footer",  "patat v" ++ version)
+                , ("footer",  "patat v" <> version)
                 , ("section", "1")
                 ]
             }
diff --git a/lib/Data/Aeson/Extended.hs b/lib/Data/Aeson/Extended.hs
--- a/lib/Data/Aeson/Extended.hs
+++ b/lib/Data/Aeson/Extended.hs
@@ -5,11 +5,10 @@
     , FlexibleNum (..)
     ) where
 
-import           Control.Applicative ((<$>))
 import           Data.Aeson
-import qualified Data.Text           as T
-import           Text.Read           (readMaybe)
+import qualified Data.Text  as T
 import           Prelude
+import           Text.Read  (readMaybe)
 
 -- | This can be parsed from a JSON string in addition to a JSON number.
 newtype FlexibleNum a = FlexibleNum {unFlexibleNum :: a}
diff --git a/lib/Patat/Main.hs b/lib/Patat/Main.hs
--- a/lib/Patat/Main.hs
+++ b/lib/Patat/Main.hs
@@ -8,14 +8,13 @@
 
 
 --------------------------------------------------------------------------------
-import           Control.Applicative          ((<$>), (<*>))
 import           Control.Concurrent           (forkIO, killThread, threadDelay)
 import           Control.Concurrent.Chan      (Chan)
 import qualified Control.Concurrent.Chan      as Chan
 import           Control.Exception            (bracket)
 import           Control.Monad                (forever, unless, when)
 import qualified Data.Aeson.Extended          as A
-import           Data.Monoid                  (mempty, (<>))
+import qualified Data.Text                    as T
 import           Data.Time                    (UTCTime)
 import           Data.Version                 (showVersion)
 import qualified Options.Applicative          as OA
@@ -121,7 +120,7 @@
 
     when (oVersion options) $ do
         putStrLn (showVersion Paths_patat.version)
-        putStrLn $ "Using pandoc: " ++ Pandoc.pandocVersion
+        putStrLn $ "Using pandoc: " ++ T.unpack Pandoc.pandocVersion
         exitSuccess
 
     filePath <- case oFilePath options of
diff --git a/lib/Patat/Presentation/Display.hs b/lib/Patat/Presentation/Display.hs
--- a/lib/Patat/Presentation/Display.hs
+++ b/lib/Patat/Presentation/Display.hs
@@ -11,13 +11,11 @@
 
 
 --------------------------------------------------------------------------------
-import           Control.Applicative                  ((<$>))
 import           Control.Monad                        (mplus, unless)
 import qualified Data.Aeson.Extended                  as A
 import           Data.Data.Extended                   (grecQ)
 import qualified Data.List                            as L
 import           Data.Maybe                           (fromMaybe)
-import           Data.Monoid                          (mconcat, mempty, (<>))
 import qualified Data.Text                            as T
 import           Patat.Cleanup
 import qualified Patat.Images                         as Images
@@ -107,7 +105,7 @@
         Just (ActiveContent fragment)
                 | Just images <- mbImages
                 , Just image <- onlyImage fragment ->
-            displayImage images image
+            displayImage images $ T.unpack image
         Just (ActiveContent fragment) ->
             displayWithBorders pres $ \_canvasSize theme ->
             prettyFragment theme fragment
@@ -229,7 +227,7 @@
         | i <- [1 .. length bss]
         ]
 
-prettyBlock _theme (Pandoc.RawBlock _ t) = PP.string t <> PP.hardline
+prettyBlock _theme (Pandoc.RawBlock _ t) = PP.text t <> PP.hardline
 
 prettyBlock _theme Pandoc.HorizontalRule = "---"
 
@@ -289,7 +287,7 @@
 
 prettyInline _theme Pandoc.Space = PP.space
 
-prettyInline _theme (Pandoc.Str str) = PP.string str
+prettyInline _theme (Pandoc.Str str) = PP.text str
 
 prettyInline theme@Theme {..} (Pandoc.Emph inlines) =
     themed themeEmph $
@@ -301,13 +299,13 @@
 
 prettyInline Theme {..} (Pandoc.Code _ txt) =
     themed themeCode $
-    PP.string (" " <> txt <> " ")
+    PP.text (" " <> txt <> " ")
 
 prettyInline theme@Theme {..} link@(Pandoc.Link _attrs text (target, _title))
     | isReferenceLink link =
         "[" <> themed themeLinkText (prettyInlines theme text) <> "]"
     | otherwise =
-        "<" <> themed themeLinkTarget (PP.string target) <> ">"
+        "<" <> themed themeLinkTarget (PP.text target) <> ">"
 
 prettyInline _theme Pandoc.SoftBreak = PP.softline
 
@@ -322,16 +320,16 @@
     "'" <> themed themeQuoted (prettyInlines theme t) <> "'"
 
 prettyInline Theme {..} (Pandoc.Math _ t) =
-    themed themeMath (PP.string t)
+    themed themeMath (PP.text t)
 
 prettyInline theme@Theme {..} (Pandoc.Image _attrs text (target, _title)) =
     "![" <> themed themeImageText (prettyInlines theme text) <> "](" <>
-    themed themeImageTarget (PP.string target) <> ")"
+    themed themeImageTarget (PP.text target) <> ")"
 
 -- These elements aren't really supported.
 prettyInline theme  (Pandoc.Cite      _ t) = prettyInlines theme t
 prettyInline theme  (Pandoc.Span      _ t) = prettyInlines theme t
-prettyInline _theme (Pandoc.RawInline _ t) = PP.string t
+prettyInline _theme (Pandoc.RawInline _ t) = PP.text t
 prettyInline theme  (Pandoc.Note        t) = prettyBlocks  theme t
 prettyInline theme  (Pandoc.Superscript t) = prettyInlines theme t
 prettyInline theme  (Pandoc.Subscript   t) = prettyInlines theme t
@@ -357,10 +355,10 @@
         "[" <>
         themed themeLinkText (prettyInlines theme $ Pandoc.newlineToSpace text) <>
         "](" <>
-        themed themeLinkTarget (PP.string target) <>
-        (if null title
+        themed themeLinkTarget (PP.text target) <>
+        (if T.null title
             then mempty
-            else PP.space <> "\"" <> PP.string title <> "\"")
+            else PP.space <> "\"" <> PP.text title <> "\"")
         <> ")"
     prettyReference _ = mempty
 
@@ -376,5 +374,5 @@
 isVisibleBlock :: Pandoc.Block -> Bool
 isVisibleBlock Pandoc.Null = False
 isVisibleBlock (Pandoc.RawBlock (Pandoc.Format "html") t) =
-    not ("<!--" `L.isPrefixOf` t && "-->" `L.isSuffixOf` t)
+    not ("<!--" `T.isPrefixOf` t && "-->" `T.isSuffixOf` t)
 isVisibleBlock _ = True
diff --git a/lib/Patat/Presentation/Display/CodeBlock.hs b/lib/Patat/Presentation/Display/CodeBlock.hs
--- a/lib/Patat/Presentation/Display/CodeBlock.hs
+++ b/lib/Patat/Presentation/Display/CodeBlock.hs
@@ -9,7 +9,6 @@
 
 --------------------------------------------------------------------------------
 import           Data.Maybe                       (mapMaybe)
-import           Data.Monoid                      (mconcat, (<>))
 import qualified Data.Text                        as T
 import           Patat.Presentation.Display.Table (themed)
 import qualified Patat.PrettyPrint                as PP
@@ -19,16 +18,16 @@
 
 
 --------------------------------------------------------------------------------
-highlight :: [String] -> String -> [Skylighting.SourceLine]
+highlight :: [T.Text] -> T.Text -> [Skylighting.SourceLine]
 highlight classes rawCodeBlock = case mapMaybe getSyntax classes of
     []        -> zeroHighlight rawCodeBlock
     (syn : _) ->
-        case Skylighting.tokenize config syn (T.pack rawCodeBlock) of
+        case Skylighting.tokenize config syn rawCodeBlock of
             Left  _  -> zeroHighlight rawCodeBlock
             Right sl -> sl
   where
-    getSyntax :: String -> Maybe Skylighting.Syntax
-    getSyntax c = Skylighting.lookupSyntax (T.pack c) syntaxMap
+    getSyntax :: T.Text -> Maybe Skylighting.Syntax
+    getSyntax c = Skylighting.lookupSyntax c syntaxMap
 
     config :: Skylighting.TokenizerConfig
     config = Skylighting.TokenizerConfig
@@ -44,13 +43,13 @@
 -- | This does fake highlighting, everything becomes a normal token.  That makes
 -- things a bit easier, since we only need to deal with one cases in the
 -- renderer.
-zeroHighlight :: String -> [Skylighting.SourceLine]
-zeroHighlight str =
-    [[(Skylighting.NormalTok, T.pack line)] | line <- lines str]
+zeroHighlight :: T.Text -> [Skylighting.SourceLine]
+zeroHighlight txt =
+    [[(Skylighting.NormalTok, line)] | line <- T.lines txt]
 
 
 --------------------------------------------------------------------------------
-prettyCodeBlock :: Theme -> [String] -> String -> PP.Doc
+prettyCodeBlock :: Theme -> [T.Text] -> T.Text -> PP.Doc
 prettyCodeBlock theme@Theme {..} classes rawCodeBlock =
     PP.vcat (map blockified sourceLines) <>
     PP.hardline
diff --git a/lib/Patat/Presentation/Display/Table.hs b/lib/Patat/Presentation/Display/Table.hs
--- a/lib/Patat/Presentation/Display/Table.hs
+++ b/lib/Patat/Presentation/Display/Table.hs
@@ -11,7 +11,6 @@
 
 --------------------------------------------------------------------------------
 import           Data.List         (intersperse, transpose)
-import           Data.Monoid       (mconcat, mempty, (<>))
 import           Patat.PrettyPrint ((<$$>))
 import qualified Patat.PrettyPrint as PP
 import           Patat.Theme       (Theme (..))
diff --git a/lib/Patat/Presentation/Fragment.hs b/lib/Patat/Presentation/Fragment.hs
--- a/lib/Patat/Presentation/Fragment.hs
+++ b/lib/Patat/Presentation/Fragment.hs
@@ -4,18 +4,17 @@
 {-# LANGUAGE DeriveFoldable    #-}
 {-# LANGUAGE DeriveFunctor     #-}
 {-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE OverloadedStrings #-}
 module Patat.Presentation.Fragment
     ( FragmentSettings (..)
     , fragmentBlocks
     , fragmentBlock
     ) where
 
-import           Data.Foldable    (Foldable)
-import           Data.List        (foldl', intersperse)
-import           Data.Maybe       (fromMaybe)
-import           Data.Traversable (Traversable)
+import           Data.List   (foldl', intersperse)
+import           Data.Maybe  (fromMaybe)
 import           Prelude
-import qualified Text.Pandoc      as Pandoc
+import qualified Text.Pandoc as Pandoc
 
 data FragmentSettings = FragmentSettings
     { fsIncrementalLists :: !Bool
diff --git a/lib/Patat/Presentation/Internal.hs b/lib/Patat/Presentation/Internal.hs
--- a/lib/Patat/Presentation/Internal.hs
+++ b/lib/Patat/Presentation/Internal.hs
@@ -34,8 +34,6 @@
 import qualified Data.Foldable          as Foldable
 import           Data.List              (intercalate)
 import           Data.Maybe             (fromMaybe, listToMaybe)
-import           Data.Monoid            (Monoid (..))
-import           Data.Semigroup         (Semigroup (..))
 import qualified Data.Text              as T
 import qualified Patat.Theme            as Theme
 import           Prelude
diff --git a/lib/Patat/Presentation/Read.hs b/lib/Patat/Presentation/Read.hs
--- a/lib/Patat/Presentation/Read.hs
+++ b/lib/Patat/Presentation/Read.hs
@@ -14,7 +14,6 @@
 import qualified Data.Aeson                  as A
 import qualified Data.HashMap.Strict         as HMS
 import           Data.Maybe                  (fromMaybe)
-import           Data.Monoid                 (mempty, (<>))
 import qualified Data.Text                   as T
 import qualified Data.Text.Encoding          as T
 import qualified Data.Text.IO                as T
diff --git a/lib/Patat/PrettyPrint.hs b/lib/Patat/PrettyPrint.hs
--- a/lib/Patat/PrettyPrint.hs
+++ b/lib/Patat/PrettyPrint.hs
@@ -44,13 +44,9 @@
 import           Control.Monad.RWS    (RWS, runRWS)
 import           Control.Monad.State  (get, gets, modify)
 import           Control.Monad.Writer (tell)
-import           Data.Foldable        (Foldable)
 import qualified Data.List            as L
-import           Data.Monoid          (Monoid, mconcat, mempty)
-import           Data.Semigroup       (Semigroup (..))
 import           Data.String          (IsString (..))
 import qualified Data.Text            as T
-import           Data.Traversable     (Traversable, traverse)
 import           Prelude              hiding (null)
 import qualified System.Console.ANSI  as Ansi
 import qualified System.IO            as IO
diff --git a/lib/Patat/Theme.hs b/lib/Patat/Theme.hs
--- a/lib/Patat/Theme.hs
+++ b/lib/Patat/Theme.hs
@@ -15,22 +15,20 @@
 
 
 --------------------------------------------------------------------------------
-import           Control.Monad           (forM_, mplus)
-import qualified Data.Aeson              as A
-import qualified Data.Aeson.TH.Extended  as A
-import           Data.Char               (toLower, toUpper)
-import           Data.Colour.SRGB        (RGB(..), sRGB24reads, toSRGB24)
-import           Data.List               (intercalate, isPrefixOf, isSuffixOf)
-import qualified Data.Map                as M
-import           Data.Maybe              (mapMaybe, maybeToList)
-import           Data.Monoid             (Monoid (..))
-import           Data.Semigroup          (Semigroup (..))
-import qualified Data.Text               as T
-import           Numeric                 (showHex)
+import           Control.Monad          (forM_, mplus)
+import qualified Data.Aeson             as A
+import qualified Data.Aeson.TH.Extended as A
+import           Data.Char              (toLower, toUpper)
+import           Data.Colour.SRGB       (RGB (..), sRGB24reads, toSRGB24)
+import           Data.List              (intercalate, isPrefixOf, isSuffixOf)
+import qualified Data.Map               as M
+import           Data.Maybe             (mapMaybe, maybeToList)
+import qualified Data.Text              as T
+import           Numeric                (showHex)
 import           Prelude
-import qualified Skylighting             as Skylighting
-import qualified System.Console.ANSI     as Ansi
-import           Text.Read               (readMaybe)
+import qualified Skylighting            as Skylighting
+import qualified System.Console.ANSI    as Ansi
+import           Text.Read              (readMaybe)
 
 
 --------------------------------------------------------------------------------
diff --git a/patat.cabal b/patat.cabal
--- a/patat.cabal
+++ b/patat.cabal
@@ -1,5 +1,5 @@
 Name:                patat
-Version:             0.8.4.3
+Version:             0.8.5.0
 Synopsis:            Terminal-based presentations using Pandoc
 Description:         Terminal-based presentations using Pandoc.
 License:             GPL-2
@@ -31,26 +31,26 @@
   Default-language:  Haskell2010
 
   Build-depends:
-    aeson                >= 0.9   && < 1.5,
-    ansi-terminal        >= 0.6   && < 0.10,
-    ansi-wl-pprint       >= 0.6   && < 0.7,
-    base                 >= 4.8   && < 5,
-    base64-bytestring    >= 1.0   && < 1.1,
-    bytestring           >= 0.10  && < 0.11,
-    colour               >= 2.3   && < 2.4,
-    containers           >= 0.5   && < 0.7,
-    directory            >= 1.2   && < 1.4,
-    filepath             >= 1.4   && < 1.5,
-    mtl                  >= 2.2   && < 2.3,
-    optparse-applicative >= 0.12  && < 0.16,
-    pandoc               >= 2.0.4 && < 2.8,
-    process              >= 1.6   && < 1.7,
-    skylighting          >= 0.1   && < 0.9,
-    terminal-size        >= 0.3   && < 0.4,
-    text                 >= 1.2   && < 1.3,
-    time                 >= 1.4   && < 1.10,
-    unordered-containers >= 0.2   && < 0.3,
-    yaml                 >= 0.8   && < 0.12,
+    aeson                >= 0.9  && < 1.5,
+    ansi-terminal        >= 0.6  && < 0.11,
+    ansi-wl-pprint       >= 0.6  && < 0.7,
+    base                 >= 4.9  && < 5,
+    base64-bytestring    >= 1.0  && < 1.1,
+    bytestring           >= 0.10 && < 0.11,
+    colour               >= 2.3  && < 2.4,
+    containers           >= 0.5  && < 0.7,
+    directory            >= 1.2  && < 1.4,
+    filepath             >= 1.4  && < 1.5,
+    mtl                  >= 2.2  && < 2.3,
+    optparse-applicative >= 0.12 && < 0.16,
+    pandoc               >= 2.9  && < 2.10,
+    process              >= 1.6  && < 1.7,
+    skylighting          >= 0.1  && < 0.9,
+    terminal-size        >= 0.3  && < 0.4,
+    text                 >= 1.2  && < 1.3,
+    time                 >= 1.4  && < 1.10,
+    unordered-containers >= 0.2  && < 0.3,
+    yaml                 >= 0.8  && < 0.12,
     -- We don't even depend on these packages but they can break cabal install
     -- because of the conflicting 'Network.URI' module.
     network-uri >= 2.6,
@@ -105,11 +105,13 @@
     Buildable: False
 
   Build-depends:
-    base   >= 4.8  && < 5,
-    mtl    >= 2.2  && < 2.3,
-    pandoc >= 2.0  && < 2.8,
-    text   >= 1.2  && < 1.3,
-    time   >= 1.6  && < 1.10
+    base         >= 4.9 && < 5,
+    containers   >= 0.6 && < 0.7,
+    doctemplates >= 0.8 && < 0.9,
+    mtl          >= 2.2 && < 2.3,
+    pandoc       >= 2.9 && < 2.10,
+    text         >= 1.2 && < 1.3,
+    time         >= 1.6 && < 1.10
 
 Test-suite patat-tests
   Main-is:          Main.hs
