diff --git a/AUTHORS.md b/AUTHORS.md
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -11,6 +11,7 @@
 - Alexander Krotov
 - Alexander Sulfrian
 - Alexander V Vershilov
+- Alexandre Franke
 - Alfred Wechselberger
 - Amogh Rathore
 - Anders Waldenborg
@@ -89,6 +90,7 @@
 - Henrik Tramberend
 - Henry de Valence
 - Hubert Plociniczak
+- Ian Max Andolina
 - Igor Khorlo
 - Ilya V. Portnov
 - Ivan Trubach
@@ -219,13 +221,11 @@
 - Uli Köhler
 - Urs Liska
 - Václav Zeman
-- Vanessa McHale
-- Viktor Kronvall
-- Vincent
 - Václav Haisman
-- Václav Zeman
 - Vanessa McHale
 - Vasily Alferov
+- Viktor Kronvall
+- Vincent
 - Wandmalfarbe
 - Waldir Pimenta
 - Wikiwide
@@ -242,7 +242,6 @@
 - csforste
 - d-dorazio
 - ebiim
-- iandol
 - infinity0x
 - jeongminkim-islab
 - kaizshang91
diff --git a/MANUAL.txt b/MANUAL.txt
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1,7 +1,7 @@
 ---
 title: Pandoc User's Guide
 author: John MacFarlane
-date: November 22, 2019
+date: November 26, 2019
 ---
 
 # Synopsis
@@ -137,7 +137,7 @@
 [`amsfonts`], [`amsmath`], [`lm`], [`unicode-math`],
 [`ifxetex`], [`ifluatex`], [`listings`] (if the
 `--listings` option is used), [`fancyvrb`], [`longtable`],
-[`booktabs`], [`graphicx`] and [`grffile`] (if the document
+[`booktabs`], [`graphicx`] (if the document
 contains images), [`hyperref`], [`xcolor`],
 [`ulem`], [`geometry`] (with the `geometry` variable set),
 [`setspace`] (with `linestretch`), and
@@ -1748,6 +1748,8 @@
 - If `variable` is an array, the material inside the loop will
   be evaluated repeatedly, with `variable` being set to each
   value of the array in turn, and concatenated.
+- If `variable` is a map, the material inside will be set to
+  the map.
 - If the value of the associated variable is not an array or
   a map, a single iteration will be performed on its value.
 
@@ -1763,6 +1765,10 @@
 ${ for(foo.bar) }
   - ${ foo.bar.last }, ${ foo.bar.first }
 ${ endfor }
+
+$for(mymap)$
+$it.name$: $it.office$
+$endfor$
 ```
 
 You may optionally specify a separator between consecutive
@@ -1933,11 +1939,9 @@
   value was an array, the `key` will be the array index,
   starting with 1.
 
-- `uppercase`:  Converts a textual value to uppercase,
-  and has no effect on other values.
+- `uppercase`:  Converts text to uppercase.
 
-- `lowercase`:  Converts a textual value to lowercase,
-  and has no effect on other values.
+- `lowercase`:  Converts text to lowercase.
 
 - `length`:  Returns the length of the value:  number
   of characters for a textual value, number of elements
@@ -1946,21 +1950,20 @@
 - `reverse`:  Reverses a textual value or array,
   and has no effect on other values.
 
-- `chomp`:  Removes trailing newlines (and breakable space)
-  from a textual value, and has no effect on other values.
+- `chomp`:  Removes trailing newlines (and breakable space).
 
-- `alpha`:  Converts a textual value that can be
-  read as an integer into a lowercase alphabetic
-  character `a..z` (mod 26), and has no effect on
-  other values.  This can be used to get lettered
+- `nowrap`:  Disables line wrapping on breakable spaces.
+
+- `alpha`:  Converts textual values that can be
+  read as an integer into lowercase alphabetic
+  characters `a..z` (mod 26). This can be used to get lettered
   enumeration from array indices.  To get uppercase
   letters, chain with `uppercase`.
 
-- `roman`:  Converts a textual value that can be
-  read as an integer into a lowercase roman numerial,
-  and has no effect on other values.  This can be used
-  to get lettered enumeration from array indices.  To
-  get uppercase roman, chain with `uppercase`.
+- `roman`:  Converts textual values that can be
+  read as an integer into lowercase roman numerials.
+  This can be used to get lettered enumeration from array indices.
+  To get uppercase roman, chain with `uppercase`.
 
 - `left n "leftborder" "rightborder"`:  Renders a textual value
   in a block of width `n`, aligned to the left, with an optional
@@ -2559,7 +2562,7 @@
 
 `toc-title`
 :   title of table of contents (works only with EPUB,
-    opendocument, odt, docx, pptx, beamer, LaTeX)
+    HTML, opendocument, odt, docx, pptx, beamer, LaTeX)
 
 [pandoc-templates]: https://github.com/jgm/pandoc-templates
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,22 @@
 # Revision history for pandoc
 
+## pandoc 2.8.0.1 (2019-11-26)
+
+  * List `pdf` in `--list-output-formats`.
+  * EPUB writer: Fix regression with `--css` (#5937).  In 2.8 `--css`
+    would not have an effect on EPUB output.
+  * RST writer: Use grid tables for one-column tables, since
+    simple tables clash with heading syntax in this case (#5936).
+  * Add unexported module Text.Pandoc.Readers.Metadata (see #5914).
+  * Use doctemplates 0.7.2, which adds the `nowrap` filter to
+    templates.
+  * Update default man template using `nowrap` for .TH heading (#5929).
+  * HTML templates: Add support for `toc-title` variable (#5930,
+    Alexandre Franke).
+  * Remove `grffile` (LaTeX package) requirement in MANUAL.txt
+    (#5927, Ian Max Andolina).
+  * Use skylighting 0.8.3.
+
 ## pandoc 2.8 (2019-11-22)
 
   * Improvements in templates system (from doctemplates):
@@ -117,7 +134,61 @@
     + Add support for `<dfn>`, parsing this as a Span with class `dfn`
       (#5882, Florian Beeres).
 
+  * Markdown reader:
 
+    + Headers: don't parse content over newline boundary (#5714).
+    + Handle inline code more eagerly within lists (Brian Leung, #5627).
+    + Removed some needless lookaheads.
+    + Don't parse footnote body unless extension enabled.
+    + Fix small super/subscript issue (#5878).  Superscripts and subscripts
+      cannot contain spaces, but newlines were previously allowed
+      (unintentionally).  This led to bad interactions in some cases
+      with footnotes.  With this change newlines are also not allowed inside
+      super/subscripts.
+    + Use `take1WhileP` for `str`, table row.  This yields a small but
+      measurable performance improvement.
+
+
+  * LaTeX reader:
+
+    + Fix parsing of optional arguments that contain braced text (#5740).
+    + Don't try to parse includes if `raw_tex` is set (#5673).
+      When the `raw_tex` extension is set, we just carry through
+      `\usepackage`, `\input`, etc. verbatim as raw LaTeX.
+    + Properly handle optional arguments for macros (#5682).
+    + Fix `\\` in `\parbox` inside a table cell (#5711).
+    + Improve `withRaw` so it can handle cases where the token string is
+      modified by a parser (e.g. accent when it only takes part of a Word
+      token) (#5686).  This fixes a bug that caused the ends of
+      certain documents to be dropped.
+    + Handle `\passthrough` macro used by latex writer (#5659).
+    + Support tex `\tt` command (#5654).
+    + Search for image with list of extensions like latex does, if an
+      extension is not provided (#4933).
+    + Handle `\looseness` command values better (#4439).
+    + Add `mbox` and `hbox` handling (Vasily Alferov, #5586).
+      When `+raw_tex` is enabled, these are passed through literally.
+      Otherwise, they are handled in a way that emulates LaTeX's behavior.
+    + Properly handle `\providecommand` and `\provideenvironment` (#5635).
+      They are now ignored if the corresponding command or environment
+      is already defined.
+    + Support epigraph command in LaTeX Reader (oquechy, #3523).
+    + Ensure that expanded macros in raw LaTeX  end with a space
+      if the original did (#4442).
+    + Treat `ly` environment from lilypond as verbatim (Urs Liska, #5671).
+    + Add `tikzcd` to list of special environments (Eigil Rischel).
+      This allows it to be processed by filters, in the same way that
+      one can do for `tikzpicture`.
+
+  * Roff reader:
+
+    + Better support for `while`.
+    + More improvements in parsing conditionals.
+    + Fix problem parsing comments before macro.
+    + Improve handling of groups.
+    + Better parsing of groups (#5410).  We now allow groups
+      where the closing `\\}` isn't at the beginning of a line.
+
   * RST reader:
 
     + Keep `name` property in `imgAttr` (Brian Leung, #5619).
@@ -567,61 +638,6 @@
 
     + Pass value of `--dpi` to `rsvg-convert` when converting SVG to PDF
       in the process of creating a PDF (#5721).
-
-  * Markdown reader:
-
-    + Headers: don't parse content over newline boundary (#5714).
-    + Handle inline code more eagerly within lists (Brian Leung, #5627).
-    + Removed some needless lookaheads.
-    + Don't parse footnote body unless extension enabled.
-    + Fix small super/subscript issue (#5878).  Superscripts and subscripts
-      cannot contain spaces, but newlines were previously allowed
-      (unintentionally).  This led to bad interactions in some cases
-      with footnotes.  With this change newlines are also not allowed inside
-      super/subscripts.
-    + Use `take1WhileP` for `str`, table row.  This yields a small but
-      measurable performance improvement.
-
-
-  * LaTeX reader:
-
-    + Fix parsing of optional arguments that contain braced text (#5740).
-    + Don't try to parse includes if `raw_tex` is set (#5673).
-      When the `raw_tex` extension is set, we just carry through
-      `\usepackage`, `\input`, etc. verbatim as raw LaTeX.
-    + Properly handle optional arguments for macros (#5682).
-    + Fix `\\` in `\parbox` inside a table cell (#5711).
-    + Improve `withRaw` so it can handle cases where the token string is
-      modified by a parser (e.g. accent when it only takes part of a Word
-      token) (#5686).  This fixes a bug that caused the ends of
-      certain documents to be dropped.
-    + Handle `\passthrough` macro used by latex writer (#5659).
-    + Support tex `\tt` command (#5654).
-    + Search for image with list of extensions like latex does, if an
-      extension is not provided (#4933).
-    + Handle `\looseness` command values better (#4439).
-    + Add `mbox` and `hbox` handling (Vasily Alferov, #5586).
-      When `+raw_tex` is enabled, these are passed through literally.
-      Otherwise, they are handled in a way that emulates LaTeX's behavior.
-    + Properly handle `\providecommand` and `\provideenvironment` (#5635).
-      They are now ignored if the corresponding command or environment
-      is already defined.
-    + Support epigraph command in LaTeX Reader (oquechy, #3523).
-    + Ensure that expanded macros in raw LaTeX  end with a space
-      if the original did (#4442).
-    + Treat `ly` environment from lilypond as verbatim (Urs Liska, #5671).
-    + Add `tikzcd` to list of special environments (Eigil Rischel).
-      This allows it to be processed by filters, in the same way that
-      one can do for `tikzpicture`.
-
-  * Roff reader:
-
-    + Better support for `while`.
-    + More improvements in parsing conditionals.
-    + Fix problem parsing comments before macro.
-    + Improve handling of groups.
-    + Better parsing of groups (#5410).  We now allow groups
-      where the closing `\\}` isn't at the beginning of a line.
 
   * Text.Pandoc.Shared:
 
diff --git a/data/templates/default.html4 b/data/templates/default.html4
--- a/data/templates/default.html4
+++ b/data/templates/default.html4
@@ -47,6 +47,9 @@
 $endif$
 $if(toc)$
 <div id="$idprefix$TOC">
+$if(toc-title)$
+<h2 id="$idprefix$toc-title">$toc-title$</h2>
+$endif$
 $table-of-contents$
 </div>
 $endif$
diff --git a/data/templates/default.html5 b/data/templates/default.html5
--- a/data/templates/default.html5
+++ b/data/templates/default.html5
@@ -50,6 +50,9 @@
 $endif$
 $if(toc)$
 <nav id="$idprefix$TOC" role="doc-toc">
+$if(toc-title)$
+<h2 id="$idprefix$toc-title">$toc-title$</h2>
+$endif$
 $table-of-contents$
 </nav>
 $endif$
diff --git a/data/templates/default.man b/data/templates/default.man
--- a/data/templates/default.man
+++ b/data/templates/default.man
@@ -8,7 +8,7 @@
 $if(adjusting)$
 .ad $adjusting$
 $endif$
-.TH "$title$" "$section$" "$date$" "$footer$" "$header$"
+.TH "$title/nowrap$" "$section/nowrap$" "$date/nowrap$" "$footer/nowrap$" "$header/nowrap$"
 $if(hyphenate)$
 .hy
 $else$
diff --git a/man/pandoc.1 b/man/pandoc.1
--- a/man/pandoc.1
+++ b/man/pandoc.1
@@ -1,5 +1,5 @@
 .\"t
-.TH PANDOC 1 "November 22, 2019" "pandoc 2.8"
+.TH PANDOC 1 "November 26, 2019" "pandoc 2.8.0.1"
 .SH NAME
 pandoc - general markup converter
 .SH SYNOPSIS
@@ -170,11 +170,11 @@
 \f[C]amsmath\f[R], \f[C]lm\f[R], \f[C]unicode-math\f[R],
 \f[C]ifxetex\f[R], \f[C]ifluatex\f[R], \f[C]listings\f[R] (if the
 \f[C]--listings\f[R] option is used), \f[C]fancyvrb\f[R],
-\f[C]longtable\f[R], \f[C]booktabs\f[R], \f[C]graphicx\f[R] and
-\f[C]grffile\f[R] (if the document contains images), \f[C]hyperref\f[R],
-\f[C]xcolor\f[R], \f[C]ulem\f[R], \f[C]geometry\f[R] (with the
-\f[C]geometry\f[R] variable set), \f[C]setspace\f[R] (with
-\f[C]linestretch\f[R]), and \f[C]babel\f[R] (with \f[C]lang\f[R]).
+\f[C]longtable\f[R], \f[C]booktabs\f[R], \f[C]graphicx\f[R] (if the
+document contains images), \f[C]hyperref\f[R], \f[C]xcolor\f[R],
+\f[C]ulem\f[R], \f[C]geometry\f[R] (with the \f[C]geometry\f[R] variable
+set), \f[C]setspace\f[R] (with \f[C]linestretch\f[R]), and
+\f[C]babel\f[R] (with \f[C]lang\f[R]).
 The use of \f[C]xelatex\f[R] or \f[C]lualatex\f[R] as the PDF engine
 requires \f[C]fontspec\f[R].
 \f[C]xelatex\f[R] uses \f[C]polyglossia\f[R] (with \f[C]lang\f[R]),
@@ -1974,6 +1974,9 @@
 evaluated repeatedly, with \f[C]variable\f[R] being set to each value of
 the array in turn, and concatenated.
 .IP \[bu] 2
+If \f[C]variable\f[R] is a map, the material inside will be set to the
+map.
+.IP \[bu] 2
 If the value of the associated variable is not an array or a map, a
 single iteration will be performed on its value.
 .PP
@@ -1990,6 +1993,10 @@
 ${ for(foo.bar) }
   - ${ foo.bar.last }, ${ foo.bar.first }
 ${ endfor }
+
+$for(mymap)$
+$it.name$: $it.office$
+$endfor$
 \f[R]
 .fi
 .PP
@@ -2185,11 +2192,9 @@
 If the original value was an array, the \f[C]key\f[R] will be the array
 index, starting with 1.
 .IP \[bu] 2
-\f[C]uppercase\f[R]: Converts a textual value to uppercase, and has no
-effect on other values.
+\f[C]uppercase\f[R]: Converts text to uppercase.
 .IP \[bu] 2
-\f[C]lowercase\f[R]: Converts a textual value to lowercase, and has no
-effect on other values.
+\f[C]lowercase\f[R]: Converts text to lowercase.
 .IP \[bu] 2
 \f[C]length\f[R]: Returns the length of the value: number of characters
 for a textual value, number of elements for a map or array.
@@ -2197,17 +2202,17 @@
 \f[C]reverse\f[R]: Reverses a textual value or array, and has no effect
 on other values.
 .IP \[bu] 2
-\f[C]chomp\f[R]: Removes trailing newlines (and breakable space) from a
-textual value, and has no effect on other values.
+\f[C]chomp\f[R]: Removes trailing newlines (and breakable space).
 .IP \[bu] 2
-\f[C]alpha\f[R]: Converts a textual value that can be read as an integer
-into a lowercase alphabetic character \f[C]a..z\f[R] (mod 26), and has
-no effect on other values.
+\f[C]nowrap\f[R]: Disables line wrapping on breakable spaces.
+.IP \[bu] 2
+\f[C]alpha\f[R]: Converts textual values that can be read as an integer
+into lowercase alphabetic characters \f[C]a..z\f[R] (mod 26).
 This can be used to get lettered enumeration from array indices.
 To get uppercase letters, chain with \f[C]uppercase\f[R].
 .IP \[bu] 2
-\f[C]roman\f[R]: Converts a textual value that can be read as an integer
-into a lowercase roman numerial, and has no effect on other values.
+\f[C]roman\f[R]: Converts textual values that can be read as an integer
+into lowercase roman numerials.
 This can be used to get lettered enumeration from array indices.
 To get uppercase roman, chain with \f[C]uppercase\f[R].
 .IP \[bu] 2
@@ -2868,8 +2873,8 @@
 non-null value if \f[C]--toc/--table-of-contents\f[R] was specified
 .TP
 \f[B]\f[CB]toc-title\f[B]\f[R]
-title of table of contents (works only with EPUB, opendocument, odt,
-docx, pptx, beamer, LaTeX)
+title of table of contents (works only with EPUB, HTML, opendocument,
+odt, docx, pptx, beamer, LaTeX)
 .SH EXTENSIONS
 .PP
 The behavior of some of the readers and writers can be adjusted by
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,5 +1,5 @@
 name:            pandoc
-version:         2.8
+version:         2.8.0.1
 cabal-version:   2.0
 build-type:      Simple
 license:         GPL-2
@@ -398,8 +398,8 @@
                  tagsoup >= 0.14.6 && < 0.15,
                  base64-bytestring >= 0.1 && < 1.1,
                  zlib >= 0.5 && < 0.7,
-                 skylighting >= 0.8.2.3 && < 0.9,
-                 skylighting-core >= 0.8.2.3 && < 0.9,
+                 skylighting >= 0.8.3 && < 0.9,
+                 skylighting-core >= 0.8.3 && < 0.9,
                  data-default >= 0.4 && < 0.8,
                  temporary >= 1.1 && < 1.4,
                  blaze-html >= 0.9 && < 0.10,
@@ -415,7 +415,7 @@
                  JuicyPixels >= 3.1.6.1 && < 3.4,
                  Glob >= 0.7 && < 0.11,
                  cmark-gfm >= 0.2 && < 0.3,
-                 doctemplates >= 0.7.1 && < 0.8,
+                 doctemplates >= 0.7.2 && < 0.8,
                  network-uri >= 2.6 && < 2.7,
                  network >= 2.6,
                  http-client >= 0.4.30 && < 0.7,
@@ -590,6 +590,7 @@
                    Text.Pandoc.Readers.Org.ParserState,
                    Text.Pandoc.Readers.Org.Parsing,
                    Text.Pandoc.Readers.Org.Shared,
+                   Text.Pandoc.Readers.Metadata,
                    Text.Pandoc.Readers.Roff,
                    Text.Pandoc.Writers.Docx.StyleMap,
                    Text.Pandoc.Writers.Roff,
@@ -733,7 +734,7 @@
                   executable-path >= 0.0 && < 0.1,
                   zip-archive >= 0.2.3.4 && < 0.5,
                   xml >= 1.3.12 && < 1.4,
-                  doctemplates >= 0.7.1 && < 0.8,
+                  doctemplates >= 0.7.2 && < 0.8,
                   Glob >= 0.7 && < 0.11
   if impl(ghc < 8.4)
      hs-source-dirs: prelude
diff --git a/src/Text/Pandoc/App.hs b/src/Text/Pandoc/App.hs
--- a/src/Text/Pandoc/App.hs
+++ b/src/Text/Pandoc/App.hs
@@ -55,12 +55,12 @@
 import Text.Pandoc.Builder (setMeta)
 import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
 import Text.Pandoc.PDF (makePDF)
-import Text.Pandoc.Readers.Markdown (yamlToMeta)
 import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
 import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
          headerShift, isURI, tabFilter, uriPathToPath, filterIpynbOutput,
          defaultUserDataDirs, tshow)
 import Text.Pandoc.Writers.Shared (lookupMetaString)
+import Text.Pandoc.Readers.Markdown (yamlToMeta)
 import qualified Text.Pandoc.UTF8 as UTF8
 #ifndef _WINDOWS
 import System.Posix.IO (stdOutput)
diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs
--- a/src/Text/Pandoc/App/CommandLineOptions.hs
+++ b/src/Text/Pandoc/App/CommandLineOptions.hs
@@ -974,7 +974,8 @@
 readersNames = sort (map (T.unpack . fst) (readers :: [(Text, Reader PandocIO)]))
 
 writersNames :: [String]
-writersNames = sort (map (T.unpack . fst) (writers :: [(Text, Writer PandocIO)]))
+writersNames = sort
+  ("pdf" : map (T.unpack . fst) (writers :: [(Text, Writer PandocIO)]))
 
 splitField :: String -> (String, String)
 splitField s =
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -20,7 +20,6 @@
 import Prelude
 import Control.Monad
 import Control.Monad.Except (throwError)
-import qualified Data.ByteString.Lazy as BS
 import Data.Char (isAlphaNum, isPunctuation, isSpace)
 import Data.List (sortBy, transpose, elemIndex)
 import qualified Data.Map as M
@@ -30,8 +29,7 @@
 import Data.Text (Text)
 import qualified Data.Text as T
 import qualified Data.Text.Lazy as TL
-import qualified Data.YAML as YAML
-import qualified Data.YAML.Event as YE
+import qualified Data.ByteString.Lazy as BL
 import System.FilePath (addExtension, takeExtension)
 import Text.HTML.TagSoup
 import Text.Pandoc.Builder (Blocks, Inlines)
@@ -49,6 +47,7 @@
 import Text.Pandoc.Shared
 import qualified Text.Pandoc.UTF8 as UTF8
 import Text.Pandoc.XML (fromEntities)
+import Text.Pandoc.Readers.Metadata (yamlBsToMeta)
 
 type MarkdownParser m = ParserT Text ParserState m
 
@@ -64,6 +63,23 @@
     Right result -> return result
     Left e       -> throwError e
 
+-- | Read a YAML string and convert it to pandoc metadata.
+-- String scalars in the YAML are parsed as Markdown.
+yamlToMeta :: PandocMonad m
+           => ReaderOptions
+           -> BL.ByteString
+           -> m Meta
+yamlToMeta opts bstr = do
+  let parser = do
+        meta <- yamlBsToMeta parseBlocks bstr
+        return $ runF meta defaultParserState
+  parsed <- readWithM parser def{ stateOptions = opts } ""
+  case parsed of
+    Right result -> return result
+    Left e       -> throwError e
+
+
+
 --
 -- Constants and data structure definitions
 --
@@ -228,110 +244,11 @@
   -- by including --- and ..., we allow yaml blocks with just comments:
   let rawYaml = T.unlines ("---" : (rawYamlLines ++ ["..."]))
   optional blanklines
-  newMetaF <- yamlBsToMeta $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
+  newMetaF <- yamlBsToMeta parseBlocks
+              $ UTF8.fromTextLazy $ TL.fromStrict rawYaml
   -- Since `<>` is left-biased, existing values are not touched:
   updateState $ \st -> st{ stateMeta' = (stateMeta' st) <> newMetaF }
   return mempty
-
--- | Read a YAML string and convert it to pandoc metadata.
--- String scalars in the YAML are parsed as Markdown.
-yamlToMeta :: PandocMonad m => ReaderOptions -> BS.ByteString -> m Meta
-yamlToMeta opts bstr = do
-  let parser = do
-        meta <- yamlBsToMeta bstr
-        return $ runF meta defaultParserState
-  parsed <- readWithM parser def{ stateOptions = opts } ""
-  case parsed of
-    Right result -> return result
-    Left e       -> throwError e
-
-yamlBsToMeta :: PandocMonad m => BS.ByteString -> MarkdownParser m (F Meta)
-yamlBsToMeta bstr = do
-  pos <- getPosition
-  case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
-       Right ((YAML.Doc (YAML.Mapping _ _ o)):_) -> (fmap Meta) <$> yamlMap o
-       Right [] -> return . return $ mempty
-       Right [YAML.Doc (YAML.Scalar _ YAML.SNull)] -> return . return $ mempty
-       Right _ -> do
-                  logMessage $
-                     CouldNotParseYamlMetadata "not an object"
-                     pos
-                  return . return $ mempty
-       Left (_pos, err') -> do
-                    logMessage $ CouldNotParseYamlMetadata
-                                 (T.pack err') pos
-                    return . return $ mempty
-
-nodeToKey :: PandocMonad m => YAML.Node YE.Pos -> m Text
-nodeToKey (YAML.Scalar _ (YAML.SStr t))       = return t
-nodeToKey (YAML.Scalar _ (YAML.SUnknown _ t)) = return t
-nodeToKey _  = throwError $ PandocParseError
-                              "Non-string key in YAML mapping"
-
-toMetaValue :: PandocMonad m
-            => Text -> MarkdownParser m (F MetaValue)
-toMetaValue x =
-   -- Note: a standard quoted or unquoted YAML value will
-   -- not end in a newline, but a "block" set off with
-   -- `|` or `>` will.
-   if "\n" `T.isSuffixOf` x
-      then parseFromString' (asBlocks <$> parseBlocks) (x <> "\n")
-      else parseFromString'
-             ((asInlines <$> try pInlines) <|> (asBlocks <$> parseBlocks))
-             x
-  where pInlines = trimInlinesF . mconcat <$> manyTill inline eof
-        asBlocks p = do
-          p' <- p
-          return $ MetaBlocks (B.toList p')
-        asInlines p = do
-          p' <- p
-          return $ MetaInlines (B.toList p')
-
-checkBoolean :: Text -> Maybe Bool
-checkBoolean t =
-  if t == T.pack "true" || t == T.pack "True" || t == T.pack "TRUE"
-     then Just True
-     else if t == T.pack "false" || t == T.pack "False" || t == T.pack "FALSE"
-             then Just False
-             else Nothing
-
-yamlToMetaValue :: PandocMonad m
-                => YAML.Node YE.Pos-> MarkdownParser m (F MetaValue)
-yamlToMetaValue (YAML.Scalar _ x) =
-  case x of
-       YAML.SStr t       -> toMetaValue t
-       YAML.SBool b      -> return $ return $ MetaBool b
-       YAML.SFloat d     -> return $ return $ MetaString $ tshow d
-       YAML.SInt i       -> return $ return $ MetaString $ tshow i
-       YAML.SUnknown _ t ->
-         case checkBoolean t of
-           Just b        -> return $ return $ MetaBool b
-           Nothing       -> toMetaValue t
-       YAML.SNull        -> return $ return $ MetaString ""
-yamlToMetaValue (YAML.Sequence _ _ xs) = do
-  xs' <- mapM yamlToMetaValue xs
-  return $ do
-    xs'' <- sequence xs'
-    return $ B.toMetaValue xs''
-yamlToMetaValue (YAML.Mapping _ _ o) = fmap B.toMetaValue <$> yamlMap o
-yamlToMetaValue _ = return $ return $ MetaString ""
-
-yamlMap :: PandocMonad m
-        => M.Map (YAML.Node YE.Pos) (YAML.Node YE.Pos)
-        -> MarkdownParser m (F (M.Map Text MetaValue))
-yamlMap o = do
-    kvs <- forM (M.toList o) $ \(key, v) -> do
-             k <- nodeToKey key
-             return (k, v)
-    let kvs' = filter (not . ignorable . fst) kvs
-    (fmap M.fromList . sequence) <$> mapM toMeta kvs'
-  where
-    ignorable t = "_" `T.isSuffixOf` t
-    toMeta (k, v) = do
-      fv <- yamlToMetaValue v
-      return $ do
-        v' <- fv
-        return (k, v')
 
 stopLine :: PandocMonad m => MarkdownParser m ()
 stopLine = try $ (string "---" <|> string "...") >> blankline >> return ()
diff --git a/src/Text/Pandoc/Readers/Metadata.hs b/src/Text/Pandoc/Readers/Metadata.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Pandoc/Readers/Metadata.hs
@@ -0,0 +1,140 @@
+{-# LANGUAGE NoImplicitPrelude   #-}
+{-# LANGUAGE RelaxedPolyRec      #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TupleSections       #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ViewPatterns        #-}
+{- |
+   Module      : Text.Pandoc.Readers.Metadata
+   Copyright   : Copyright (C) 2006-2019 John MacFarlane
+   License     : GNU GPL, version 2 or above
+
+   Maintainer  : John MacFarlane <jgm@berkeley.edu>
+   Stability   : alpha
+   Portability : portable
+
+Parse YAML/JSON metadata to 'Pandoc' 'Meta'.
+-}
+module Text.Pandoc.Readers.Metadata ( yamlBsToMeta ) where
+
+import Prelude
+import Control.Monad
+import Control.Monad.Except (throwError)
+import qualified Data.ByteString.Lazy as BL
+import qualified Data.Map as M
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.YAML as YAML
+import qualified Data.YAML.Event as YE
+import qualified Text.Pandoc.Builder as B
+import Text.Pandoc.Builder (Blocks)
+import Text.Pandoc.Class (PandocMonad (..))
+import Text.Pandoc.Definition
+import Text.Pandoc.Error
+import Text.Pandoc.Logging
+import Text.Pandoc.Parsing hiding (tableWith)
+import Text.Pandoc.Shared
+
+yamlBsToMeta :: PandocMonad m
+             => ParserT Text ParserState m (F Blocks)
+             -> BL.ByteString
+             -> ParserT Text ParserState m (F Meta)
+yamlBsToMeta pBlocks bstr = do
+  pos <- getPosition
+  case YAML.decodeNode' YAML.failsafeSchemaResolver False False bstr of
+       Right ((YAML.Doc (YAML.Mapping _ _ o)):_)
+                -> (fmap Meta) <$> yamlMap pBlocks o
+       Right [] -> return . return $ mempty
+       Right [YAML.Doc (YAML.Scalar _ YAML.SNull)]
+                -> return . return $ mempty
+       Right _  -> do logMessage $ CouldNotParseYamlMetadata "not an object"
+                                   pos
+                      return . return $ mempty
+       Left (_pos, err')
+                -> do logMessage $ CouldNotParseYamlMetadata
+                                   (T.pack err') pos
+                      return . return $ mempty
+
+nodeToKey :: PandocMonad m
+          => YAML.Node YE.Pos
+          -> m Text
+nodeToKey (YAML.Scalar _ (YAML.SStr t))       = return t
+nodeToKey (YAML.Scalar _ (YAML.SUnknown _ t)) = return t
+nodeToKey _  = throwError $ PandocParseError
+                              "Non-string key in YAML mapping"
+
+toMetaValue :: PandocMonad m
+            => ParserT Text ParserState m (F Blocks)
+            -> Text
+            -> ParserT Text ParserState m (F MetaValue)
+toMetaValue pBlocks x =
+   -- Note: a standard quoted or unquoted YAML value will
+   -- not end in a newline, but a "block" set off with
+   -- `|` or `>` will.
+   if "\n" `T.isSuffixOf` x
+      then parseFromString' (asBlocks <$> pBlocks) (x <> "\n")
+      else parseFromString' pInlines x
+  where pInlines = do
+          bs <- pBlocks
+          return $ do
+            bs' <- bs
+            return $
+              case B.toList bs' of
+                [Plain ils] -> MetaInlines ils
+                [Para ils]  -> MetaInlines ils
+                xs          -> MetaBlocks xs
+        asBlocks p = do
+          p' <- p
+          return $ MetaBlocks (B.toList p')
+
+checkBoolean :: Text -> Maybe Bool
+checkBoolean t =
+  if t == T.pack "true" || t == T.pack "True" || t == T.pack "TRUE"
+     then Just True
+     else if t == T.pack "false" || t == T.pack "False" || t == T.pack "FALSE"
+             then Just False
+             else Nothing
+
+yamlToMetaValue :: PandocMonad m
+                => ParserT Text ParserState m (F Blocks)
+                -> YAML.Node YE.Pos
+                -> ParserT Text ParserState m (F MetaValue)
+yamlToMetaValue pBlocks (YAML.Scalar _ x) =
+  case x of
+       YAML.SStr t       -> toMetaValue pBlocks t
+       YAML.SBool b      -> return $ return $ MetaBool b
+       YAML.SFloat d     -> return $ return $ MetaString $ tshow d
+       YAML.SInt i       -> return $ return $ MetaString $ tshow i
+       YAML.SUnknown _ t ->
+         case checkBoolean t of
+           Just b        -> return $ return $ MetaBool b
+           Nothing       -> toMetaValue pBlocks t
+       YAML.SNull        -> return $ return $ MetaString ""
+
+yamlToMetaValue pBlocks (YAML.Sequence _ _ xs) = do
+  xs' <- mapM (yamlToMetaValue pBlocks) xs
+  return $ do
+    xs'' <- sequence xs'
+    return $ B.toMetaValue xs''
+yamlToMetaValue pBlocks (YAML.Mapping _ _ o) =
+  fmap B.toMetaValue <$> yamlMap pBlocks o
+yamlToMetaValue _ _ = return $ return $ MetaString ""
+
+yamlMap :: PandocMonad m
+        => ParserT Text ParserState m (F Blocks)
+        -> M.Map (YAML.Node YE.Pos) (YAML.Node YE.Pos)
+        -> ParserT Text ParserState m (F (M.Map Text MetaValue))
+yamlMap pBlocks o = do
+    kvs <- forM (M.toList o) $ \(key, v) -> do
+             k <- nodeToKey key
+             return (k, v)
+    let kvs' = filter (not . ignorable . fst) kvs
+    (fmap M.fromList . sequence) <$> mapM toMeta kvs'
+  where
+    ignorable t = "_" `T.isSuffixOf` t
+    toMeta (k, v) = do
+      fv <- yamlToMetaValue pBlocks v
+      return $ do
+        v' <- fv
+        return (k, v')
+
diff --git a/src/Text/Pandoc/Writers/EPUB.hs b/src/Text/Pandoc/Writers/EPUB.hs
--- a/src/Text/Pandoc/Writers/EPUB.hs
+++ b/src/Text/Pandoc/Writers/EPUB.hs
@@ -357,8 +357,12 @@
             `mplus` (metaValueToString <$> lookupMeta "cover-image" meta)
         mCss = lookupMeta "css" meta <|> lookupMeta "stylesheet" meta
         stylesheets = fromMaybe [] (metaValueToPaths <$> mCss) ++
-                      maybe [] (\t -> [TS.unpack t])
-                        (lookupContext "css" (writerVariables opts))
+                      case lookupContext "css" (writerVariables opts) of
+                         Just xs -> map TS.unpack xs
+                         Nothing ->
+                           case lookupContext "css" (writerVariables opts) of
+                             Just x  -> [TS.unpack x]
+                             Nothing -> []
         pageDirection = case map toLower . metaValueToString <$>
                              lookupMeta "page-progression-direction" meta of
                               Just "ltr" -> Just LTR
@@ -440,13 +444,13 @@
                M.insert "lang" (toVal' $ epubLanguage metadata)
              $ unContext $ writerVariables opts
 
-  let cssvars useprefix = Context $ M.fromList $ map
-                       (\e -> ("css", toVal' $
-                               (if useprefix
-                                   then "../"
-                                   else "")
-                               ++ makeRelative epubSubdir (eRelativePath e)))
-                          stylesheetEntries
+  let cssvars useprefix = Context $ M.insert "css"
+                           (ListVal $ map
+                             (\e -> toVal' $
+                                (if useprefix then "../" else "") <>
+                                makeRelative epubSubdir (eRelativePath e))
+                             stylesheetEntries)
+                             mempty
 
   let opts' = opts{ writerEmailObfuscation = NoObfuscation
                   , writerSectionDivs = True
diff --git a/src/Text/Pandoc/Writers/RST.hs b/src/Text/Pandoc/Writers/RST.hs
--- a/src/Text/Pandoc/Writers/RST.hs
+++ b/src/Text/Pandoc/Writers/RST.hs
@@ -294,7 +294,7 @@
          modify $ \st -> st{ stOptions = oldOpts }
          return result
   opts <- gets stOptions
-  let isSimple = all (== 0) widths
+  let isSimple = all (== 0) widths && length widths > 1
   tbl <- if isSimple
             then do
               tbl' <- simpleTable opts blocksToDoc headers rows
diff --git a/stack.yaml b/stack.yaml
--- a/stack.yaml
+++ b/stack.yaml
@@ -15,13 +15,13 @@
 - pandoc-types-1.20
 - texmath-0.12
 - haddock-library-1.8.0
-- skylighting-0.8.2.3
-- skylighting-core-0.8.2.3
+- skylighting-0.8.3
+- skylighting-core-0.8.3
 - regex-pcre-builtin-0.95.0.8.8.35
 - doclayout-0.2.0.1
 - HsYAML-0.2.0.0
 - HsYAML-aeson-0.2.0.0
-- doctemplates-0.7.1
+- doctemplates-0.7.2
 - pandoc-citeproc-0.16.4
 ghc-options:
    "$locals": -fhide-source-paths -Wno-missing-home-modules
diff --git a/test/command/5936.md b/test/command/5936.md
new file mode 100644
--- /dev/null
+++ b/test/command/5936.md
@@ -0,0 +1,40 @@
+```
+% pandoc -f gfm -t rst
+| Name |
+| ---- |
+| Foo  |
+| Bar  |
+| Baz  |
+| Quux |
+^D
++------+
+| Name |
++======+
+| Foo  |
++------+
+| Bar  |
++------+
+| Baz  |
++------+
+| Quux |
++------+
+```
+
+```
+% pandoc -f gfm -t rst
+| Name | Number |
+| ---- | ------ |
+| Foo  | 3 |
+| Bar  | 4 |
+| Baz  | 2 |
+| Quux | 1 |
+^D
+==== ======
+Name Number
+==== ======
+Foo  3
+Bar  4
+Baz  2
+Quux 1
+==== ======
+```
diff --git a/trypandoc/trypandoc.hs b/trypandoc/trypandoc.hs
--- a/trypandoc/trypandoc.hs
+++ b/trypandoc/trypandoc.hs
@@ -41,12 +41,12 @@
   text <- getParam "text" >>= checkLength . fromMaybe T.empty
   fromFormat <- fromMaybe "" <$> getParam "from"
   toFormat <- fromMaybe "" <$> getParam "to"
-  let reader = case runPure $ getReader (T.unpack fromFormat) of
+  let reader = case runPure $ getReader fromFormat of
                     Right (TextReader r, es) -> r readerOpts{
                        readerExtensions = es }
                     _ -> error $ "could not find reader for "
                                   ++ T.unpack fromFormat
-  let writer = case runPure $ getWriter (T.unpack toFormat) of
+  let writer = case runPure $ getWriter toFormat of
                     Right (TextWriter w, es) -> w writerOpts{
                        writerExtensions = es }
                     _ -> error $ "could not find writer for " ++
@@ -71,8 +71,8 @@
 writerOpts :: WriterOptions
 writerOpts = def { writerReferenceLinks = True,
                    writerEmailObfuscation = NoObfuscation,
-                   writerHTMLMathMethod = MathJax (defaultMathJaxURL ++
-                       "tex-mml-chtml.js"),
+                   writerHTMLMathMethod = MathJax (defaultMathJaxURL <>
+                       T.pack "tex-mml-chtml.js"),
                    writerHighlightStyle = Just pygments }
 
 readerOpts :: ReaderOptions
