diff --git a/AUTHORS.md b/AUTHORS.md
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -1,6 +1,7 @@
 # Contributors
 
 - Aaron Wolen
+- Adelar da Silva Queiróz
 - Agustín Martín Barbero
 - Akos Marton
 - Albert Krewinkel
@@ -269,6 +270,7 @@
 - Nixon Enraght-Moony
 - Noah Malmed
 - Nokome Bentley
+- Norwid Behrnd
 - OCzarnecki
 - Ola Wolska
 - Ole Martin Ruud
@@ -284,6 +286,7 @@
 - Paul Tilley
 - Paulo Tanimoto
 - Pavol Otto
+- Per Christian Gaustad
 - Pete Ryland
 - Peter Fabinksi
 - Peter Wang
@@ -389,7 +392,9 @@
 - damon-sava-stanley
 - dbecher-ito
 - ebiim
+- ech0
 - favonia
+- harabat
 - hseg
 - infinity0x
 - jeongminkim-islab
diff --git a/INSTALL.md b/INSTALL.md
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -43,8 +43,9 @@
 installations of pandoc; it is recommended to properly uninstall
 pandoc before switching to an alternative installation method.
 
-By default, Pandoc creates PDFs using LaTeX.
-We recommend installing it via [MiKTeX].
+By default, Pandoc creates PDFs using LaTeX.  We recommend
+installing it via [MiKTeX]. With the option `--pdf-engine`,
+you however can specify other programs for this task.
 
 ## macOS
 
@@ -82,6 +83,9 @@
 
     tlmgr install collection-fontsrecommended
 
+With the option `--pdf-engine`, you however can specify other programs
+for this task.
+
 ## Linux
 
 Check whether the pandoc version in your package manager is
@@ -124,9 +128,10 @@
 package repositories.  For example, on Debian/Ubuntu,
 you can install it with `apt-get install haskell-platform`.
 
-For PDF output, you'll need LaTeX.  We recommend installing
+By default, Pandoc creates PDFs using LaTeX.  We recommend installing
 [TeX Live](https://www.tug.org/texlive/) via your package
-manager.  (On Debian/Ubuntu, `apt-get install texlive`.)
+manager.  (On Debian/Ubuntu, `apt-get install texlive`.)  With the option
+`--pdf-engine`, you however can specify other programs for this task.
 
 ## Chrome OS
 
@@ -361,9 +366,9 @@
     cabal bench --benchmark-options='markdown'
 
 
-[Arch]: https://www.archlinux.org/packages/community/x86_64/pandoc/
+[Arch]: https://archlinux.org/packages/?q=pandoc
 [Cabal User's Guide]: https://cabal.readthedocs.io/
-[Debian]: https://packages.debian.org/pandoc
+[Debian]: https://packages.debian.org/search?keywords=pandoc
 [Fedora]: https://packages.fedoraproject.org/pkgs/pandoc/pandoc/
 [FreeBSD ports]: https://www.freshports.org/textproc/hs-pandoc/
 [GHC]:  https://www.haskell.org/ghc/
@@ -377,9 +382,9 @@
 [librsvg]: https://wiki.gnome.org/Projects/LibRsvg
 [Python]: https://www.python.org
 [NetBSD]: https://pkgsrc.se/converters/pandoc
-[NixOS]: https://nixos.org/nixos/packages.html
+[NixOS]: https://search.nixos.org/packages?query=pandoc
 [Slackware]: https://www.slackbuilds.org/result/?search=pandoc&sv=
-[Ubuntu]: https://packages.ubuntu.com/pandoc
+[Ubuntu]: https://packages.ubuntu.com/search?keywords=pandoc
 [download page]: https://github.com/jgm/pandoc/releases/latest
 [gentoo]: https://packages.gentoo.org/package/app-text/pandoc
 [haskell repository]: https://wiki.archlinux.org/index.php/Haskell_Package_Guidelines#.5Bhaskell.5D
@@ -387,5 +392,5 @@
 [source tarball]: https://hackage.haskell.org/package/pandoc
 [stack]: https://docs.haskellstack.org/en/stable/install_and_upgrade.html
 [cabal-install]: https://hackage.haskell.org/package/cabal-install
-[Void]: https://voidlinux.org/
+[Void]: https://voidlinux.org/packages/?arch=x86_64&q=pandoc
 [uninstaller]: https://raw.githubusercontent.com/jgm/pandoc/main/macos/uninstall-pandoc.pl
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: June 6, 2023
+date: June 24, 2023
 ---
 
 # Synopsis
@@ -2566,7 +2566,7 @@
     documents
 
 `abstract-title`
-:   title of abstract, currently used only in HTML and EPUB.
+:   title of abstract, currently used only in HTML, EPUB, and docx.
     This will be set automatically to a localized value,
     depending on `lang`, but can be manually overridden.
 
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,87 @@
 # Revision history for pandoc
 
+## pandoc 3.1.4 (2023-06-24)
+
+  * Fix a security vulnerability in MediaBag and T.P.Class.IO.writeMedia.
+    This vulnerability, discovered by Entroy C, allows users to write
+    arbitrary files to any location by feeding pandoc a specially crafted
+    URL in an image element.  The vulnerability is serious for anyone
+    using pandoc to process untrusted input.  The vulnerability does
+    not affect pandoc when run with the `--sandbox` flag.
+
+  * Allow `epub-title-page` to be used in defaults files (#8908).
+
+  * Issue `Extracting` info message (in `--verbose` mode) when using
+    `--extract-media` or extracting media temporarily in PDF production.
+
+  * HTML reader: Update TableBody RowHeadColumns caculation (#8634,
+    Ruqi). This change sets RowHeadColumns to the minimum value of each row,
+    which gives better results in cases where rows have different numbers
+    of leading th tags.
+
+  * Dokuwiki reader: retain image query parameters as attributes (#8887, echo0).
+
+  * Textile reader: Add support for link references (#8706, Stephen Altamirano).
+    Textile supports what it calls "link alias", which are analogous to
+    Markdown's reference-style links.
+
+  * LaTeX reader: support alt text on images (#8743, Albert Krewinkel).
+
+  * Commonmark reader: Make `implicit_figures` work again.
+    Support for this (introduced in #6350) disappeared when we made an
+    architectural change.
+
+  * JATS reader:
+
+    + Add footer and multiple body parsing to table reader (#8765, Noah Malmed).
+    + Parse references title from ref-list (#8365).
+
+  * JATS writer:
+
+     + Make `--number-sections` work.
+     + Include title in ref-list (#8364). Previously the reference title ended
+       up in a separate section at the back of the body instead of in the ref-list
+       in the back matter.
+
+  * Mediawiki writer: allow highlighting to work for F# language
+    (Adelar da Silva Queiróz).
+
+  * LaTeX writer: Fix escaping of `&` in `\href` and `\url` (#8903).
+
+  * Docx writer:
+
+    + Fix localization of "Abstract" title (#8702).
+    + Allow `abstract-title` to be specified in docx metadata (#8794).
+
+  * ChunkedHTML writer: Make math work in top-level page (#8915).
+
+  * Text.Pandoc.Logging: add new log message type `ScriptingWarning`
+    [API change] (Albert Krewinkel).
+
+  * Lua: report warnings from Lua scripts (Albert Krewinkel).
+    Lua's warning system is plugged into pandoc's reporting architecture.
+    Warnings that are raised with the Lua `warn` function are now reported
+    together with other messages.
+
+  * Use crypton-connection instead of connection (#8896, Felix Yan).
+    Follows the change introduced in tls 1.7.0.
+
+  * Bump versions for skylighting-core, skylighting.
+
+  * Include lua/module/sample.svg in cabal extra-source-files (Felix Yan).
+
+  * Add Nynorsk (New Norwegian) translations (Per Christian Gaustad).
+
+  * Add tests for `fillMediaBag`/`extractMedia`.
+
+  * INSTALL.md:
+
+    + Mention alternatives to LaTeX to generate PDF (Norwid Behrnd).
+    + Update Linux install links (harabat).
+
+  * pandoc-extras.md: add to "Academic publishing workflows" (#8696,
+    Vladimir Alexiev).
+
 ## pandoc 3.1.3 (2023-06-07)
 
   * New output format: `typst`.
diff --git a/data/translations/nn.yaml b/data/translations/nn.yaml
new file mode 100644
--- /dev/null
+++ b/data/translations/nn.yaml
@@ -0,0 +1,21 @@
+Abstract: Samandrag
+Appendix: Tillegg
+Bibliography: Bibliografi
+Cc: Kopi sendt
+Chapter: Kapittel
+Contents: Innhald
+Encl: Vedlegg
+Figure: Figur
+Glossary: Ordliste
+Index: Register
+ListOfFigures: Figurar
+ListOfTables: Tabellar
+Page: Side
+Part: Del
+Preface: Forord
+Proof: Bevis
+References: Referansar
+See: Sjå
+SeeAlso: Sjå òg
+Table: Tabell
+To: Til
diff --git a/man/pandoc.1 b/man/pandoc.1
--- a/man/pandoc.1
+++ b/man/pandoc.1
@@ -1,4 +1,4 @@
-.\" Automatically generated by Pandoc 3.1.2
+.\" Automatically generated by Pandoc 3.1.3
 .\"
 .\" Define V font for inline verbatim, using C font in formats
 .\" that render this, and otherwise B font.
@@ -14,7 +14,7 @@
 . ftr VB CB
 . ftr VBI CBI
 .\}
-.TH "Pandoc User\[cq]s Guide" "" "June 6, 2023" "pandoc 3.1.3" ""
+.TH "Pandoc User\[cq]s Guide" "" "June 24, 2023" "pandoc 3.1.4" ""
 .hy
 .SH NAME
 pandoc - general markup converter
@@ -2625,7 +2625,7 @@
 documents
 .TP
 \f[V]abstract-title\f[R]
-title of abstract, currently used only in HTML and EPUB.
+title of abstract, currently used only in HTML, EPUB, and docx.
 This will be set automatically to a localized value, depending on
 \f[V]lang\f[R], but can be manually overridden.
 .TP
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,6 +1,6 @@
 cabal-version:   2.4
 name:            pandoc
-version:         3.1.3
+version:         3.1.4
 build-type:      Simple
 license:         GPL-2.0-or-later
 license-file:    COPYING.md
@@ -478,8 +478,8 @@
                  commonmark            >= 0.2.2    && < 0.3,
                  commonmark-extensions >= 0.2.3.4  && < 0.3,
                  commonmark-pandoc     >= 0.2.1.3  && < 0.3,
-                 connection            >= 0.3.1,
                  containers            >= 0.6.0.1  && < 0.7,
+                 crypton-connection    >= 0.3.1    && < 0.4,
                  data-default          >= 0.4      && < 0.8,
                  deepseq               >= 1.3      && < 1.5,
                  directory             >= 1.2.3    && < 1.4,
@@ -499,7 +499,7 @@
                  jira-wiki-markup      >= 1.5.1    && < 1.6,
                  mime-types            >= 0.1.1    && < 0.2,
                  mtl                   >= 2.2      && < 2.4,
-                 network               >= 2.6,
+                 network               >= 2.6      && < 3.2,
                  network-uri           >= 2.6      && < 2.8,
                  pandoc-types          >= 1.23     && < 1.24,
                  parsec                >= 3.1      && < 3.2,
@@ -509,8 +509,8 @@
                  random                >= 1        && < 1.3,
                  safe                  >= 0.3.18   && < 0.4,
                  scientific            >= 0.3      && < 0.4,
-                 skylighting           >= 0.13.2.1 && < 0.14,
-                 skylighting-core      >= 0.13.2.1 && < 0.14,
+                 skylighting           >= 0.13.3   && < 0.14,
+                 skylighting-core      >= 0.13.3   && < 0.14,
                  split                 >= 0.2      && < 0.3,
                  syb                   >= 0.1      && < 0.8,
                  tagsoup               >= 0.14.6   && < 0.15,
@@ -767,6 +767,7 @@
                   tasty-hunit       >= 0.9     && < 0.11,
                   tasty-quickcheck  >= 0.8     && < 0.11,
                   text              >= 1.1.1.0 && < 2.1,
+                  temporary         >= 1.1     && < 1.4,
                   time              >= 1.5     && < 1.14,
                   xml               >= 1.3.12  && < 1.4,
                   zip-archive       >= 0.4.3   && < 0.5
@@ -774,6 +775,7 @@
                   Tests.Command
                   Tests.Helpers
                   Tests.Shared
+                  Tests.MediaBag
                   Tests.Readers.LaTeX
                   Tests.Readers.HTML
                   Tests.Readers.JATS
diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs
--- a/src/Text/Pandoc/App/Opt.hs
+++ b/src/Text/Pandoc/App/Opt.hs
@@ -570,6 +570,8 @@
     "epub-cover-image" ->
       parseJSON v >>= \x ->
              return (\o -> o{ optEpubCoverImage = unpack <$> x })
+    "epub-title-page" ->
+      parseJSON v >>= \x -> return (\o -> o{ optEpubTitlePage = x })
     "toc-depth" ->
       parseJSON v >>= \x -> return (\o -> o{ optTOCDepth = x })
     "dump-args" ->
diff --git a/src/Text/Pandoc/Class/IO.hs b/src/Text/Pandoc/Class/IO.hs
--- a/src/Text/Pandoc/Class/IO.hs
+++ b/src/Text/Pandoc/Class/IO.hs
@@ -50,7 +50,7 @@
 import Network.HTTP.Client.TLS (mkManagerSettings)
 import Network.HTTP.Types.Header ( hContentType )
 import Network.Socket (withSocketsDo)
-import Network.URI (unEscapeString)
+import Network.URI (URI(..), parseURI, unEscapeString)
 import System.Directory (createDirectoryIfMissing)
 import System.Environment (getEnv)
 import System.FilePath ((</>), takeDirectory, normalise)
@@ -122,11 +122,11 @@
 
 openURL :: (PandocMonad m, MonadIO m) => Text -> m (B.ByteString, Maybe MimeType)
 openURL u
- | Just u'' <- T.stripPrefix "data:" u = do
-     let mime     = T.takeWhile (/=',') u''
-     let contents = UTF8.fromString $
-                     unEscapeString $ T.unpack $ T.drop 1 $ T.dropWhile (/=',') u''
-     return (decodeBase64Lenient contents, Just mime)
+ | Just (URI{ uriScheme = "data:",
+              uriPath = upath }) <- parseURI (T.unpack u) = do
+     let (mime, rest) = break (== ',') $ unEscapeString upath
+     let contents = UTF8.fromString $ drop 1 rest
+     return (decodeBase64Lenient contents, Just (T.pack mime))
  | otherwise = do
      let toReqHeader (n, v) = (CI.mk (UTF8.fromText n), UTF8.fromText v)
      customHeaders <- map toReqHeader <$> getsCommonState stRequestHeaders
@@ -226,6 +226,7 @@
   -- we normalize to get proper path separators for the platform
   let fullpath = normalise $ dir </> unEscapeString fp
   liftIOError (createDirectoryIfMissing True) (takeDirectory fullpath)
+  report $ Extracting (T.pack fullpath)
   logIOError $ BL.writeFile fullpath bs
 
 -- | If the given Inline element is an image with a @src@ path equal to
diff --git a/src/Text/Pandoc/Logging.hs b/src/Text/Pandoc/Logging.hs
--- a/src/Text/Pandoc/Logging.hs
+++ b/src/Text/Pandoc/Logging.hs
@@ -79,6 +79,7 @@
   | Fetching Text
   | Extracting Text
   | LoadedResource FilePath FilePath
+  | ScriptingWarning Text (Maybe SourcePos)
   | NoTitleElement Text
   | NoLangSpecified
   | InvalidLang Text
@@ -200,6 +201,14 @@
       LoadedResource orig found ->
            ["for"  .= orig
            ,"from" .= found]
+      ScriptingWarning msg mbpos ->
+           ["message" .= msg] <>
+           case mbpos of
+             Nothing  -> []
+             Just pos -> ["source" .= sourceName pos
+                         ,"line" .= toJSON (sourceLine pos)
+                         ,"column" .= toJSON (sourceColumn pos)
+                         ]
       NoTitleElement fallback ->
            ["fallback" .= fallback]
       NoLangSpecified -> []
@@ -322,6 +331,9 @@
          "Extracting " <> fp <> "..."
        LoadedResource orig found ->
          "Loaded " <> Text.pack orig <> " from " <> Text.pack found
+       ScriptingWarning s mbpos ->
+         "Scripting warning" <>
+         maybe "" (\pos -> " at " <> showPos pos) mbpos  <> ": " <> s
        NoTitleElement fallback ->
          "This document format requires a nonempty <title> element.\n" <>
          "Defaulting to '" <> fallback <> "' as the title.\n" <>
@@ -408,6 +420,7 @@
        Fetching{}                    -> INFO
        Extracting{}                  -> INFO
        LoadedResource{}              -> INFO
+       ScriptingWarning{}            -> WARNING
        NoTitleElement{}              -> WARNING
        NoLangSpecified               -> INFO
        InvalidLang{}                 -> WARNING
diff --git a/src/Text/Pandoc/MediaBag.hs b/src/Text/Pandoc/MediaBag.hs
--- a/src/Text/Pandoc/MediaBag.hs
+++ b/src/Text/Pandoc/MediaBag.hs
@@ -28,6 +28,7 @@
 import qualified Data.Map as M
 import Data.Maybe (fromMaybe, isNothing)
 import Data.Typeable (Typeable)
+import Network.URI (unEscapeString)
 import System.FilePath
 import qualified System.FilePath.Posix as Posix
 import qualified System.FilePath.Windows as Windows
@@ -35,7 +36,8 @@
 import Data.Text (Text)
 import qualified Data.Text as T
 import Data.Digest.Pure.SHA (sha1, showDigest)
-import Network.URI (URI (..), parseURI)
+import Network.URI (URI (..), parseURI, isURI)
+import Data.List (isInfixOf)
 
 data MediaItem =
   MediaItem
@@ -54,9 +56,12 @@
 instance Show MediaBag where
   show bag = "MediaBag " ++ show (mediaDirectory bag)
 
--- | We represent paths with /, in normalized form.
+-- | We represent paths with /, in normalized form.  Percent-encoding
+-- is not resolved.
 canonicalize :: FilePath -> Text
-canonicalize = T.replace "\\" "/" . T.pack . normalise
+canonicalize fp
+  | isURI fp = T.pack fp
+  | otherwise = T.replace "\\" "/" . T.pack . normalise $ fp
 
 -- | Delete a media item from a 'MediaBag', or do nothing if no item corresponds
 -- to the given path.
@@ -79,22 +84,22 @@
                              , mediaContents = contents
                              , mediaMimeType = mt }
         fp' = canonicalize fp
+        fp'' = unEscapeString $ T.unpack fp'
         uri = parseURI fp
-        newpath = if Posix.isRelative fp
-                       && Windows.isRelative fp
+        newpath = if Posix.isRelative fp''
+                       && Windows.isRelative fp''
                        && isNothing uri
-                       && ".." `notElem` splitDirectories fp
-                     then T.unpack fp'
+                       && not (".." `isInfixOf` fp'')
+                     then fp''
                      else showDigest (sha1 contents) <> "." <> ext
-        fallback = case takeExtension fp of
-                        ".gz" -> getMimeTypeDef $ dropExtension fp
-                        _     -> getMimeTypeDef fp
+        fallback = case takeExtension fp'' of
+                        ".gz" -> getMimeTypeDef $ dropExtension fp''
+                        _     -> getMimeTypeDef fp''
         mt = fromMaybe fallback mbMime
-        path = maybe fp uriPath uri
+        path = maybe fp'' (unEscapeString . uriPath) uri
         ext = case takeExtension path of
                 '.':e -> e
                 _ -> maybe "" T.unpack $ extensionFromMimeType mt
-
 
 -- | Lookup a media item in a 'MediaBag', returning mime type and contents.
 lookupMedia :: FilePath
diff --git a/src/Text/Pandoc/Readers/CommonMark.hs b/src/Text/Pandoc/Readers/CommonMark.hs
--- a/src/Text/Pandoc/Readers/CommonMark.hs
+++ b/src/Text/Pandoc/Readers/CommonMark.hs
@@ -71,6 +71,13 @@
     let toks = concatMap sourceToToks (unSources sources)
     readCommonMarkBody opts sources toks
 
+makeFigures :: Block -> Block
+makeFigures (Para [Image (ident,classes,kvs) alt (src,tit)]) =
+  Figure (ident,[],[])
+    (Caption Nothing [Plain alt])
+    [Plain [Image ("",classes,kvs) alt (src,tit)]]
+makeFigures b = b
+
 sourceToToks :: (SourcePos, Text) -> [Tok]
 sourceToToks (pos, s) = map adjust $ tokenize (sourceName pos) s
  where
@@ -91,6 +98,9 @@
 
 readCommonMarkBody :: PandocMonad m => ReaderOptions -> Sources -> [Tok] -> m Pandoc
 readCommonMarkBody opts s toks =
+  (if isEnabled Ext_implicit_figures opts
+      then walk makeFigures
+      else id) .
   (if readerStripComments opts
       then walk stripBlockComments . walk stripInlineComments
       else id) <$>
diff --git a/src/Text/Pandoc/Readers/DokuWiki.hs b/src/Text/Pandoc/Readers/DokuWiki.hs
--- a/src/Text/Pandoc/Readers/DokuWiki.hs
+++ b/src/Text/Pandoc/Readers/DokuWiki.hs
@@ -389,7 +389,11 @@
         parameterList = T.splitOn "&" $ T.drop 1 parameters
         linkOnly = "linkonly" `elem` parameterList
         (width, height) = maybe (Nothing, Nothing) parseWidthHeight (F.find isWidthHeightParameter parameterList)
-        attributes = catMaybes [fmap ("width",) width, fmap ("height",) height]
+        attributes = catMaybes [
+                fmap ("width",) width,
+                fmap ("height",) height,
+                fmap ("query",) (if T.null parameters then Nothing else Just parameters)
+            ]
         defaultDescription = B.str $ urlToText path'
 
 -- * Block parsers
diff --git a/src/Text/Pandoc/Readers/HTML/Table.hs b/src/Text/Pandoc/Readers/HTML/Table.hs
--- a/src/Text/Pandoc/Readers/HTML/Table.hs
+++ b/src/Text/Pandoc/Readers/HTML/Table.hs
@@ -191,10 +191,12 @@
   optional $ pSatisfy (matchTagClose "tbody")
   guard $ isJust mbattribs || not (null bodyheads && null rows)
   let attribs = fromMaybe [] mbattribs
-  return $ TableBody (toAttr attribs) (foldr max 0 rowheads) bodyheads rows
+  return $ TableBody (toAttr attribs) (getMin rowheads) bodyheads rows
   where
     getAttribs (TagOpen _ attribs) = attribs
     getAttribs _ = []
+    getMin [] = 0
+    getMin (x:xs) = foldr min x xs
 
 -- | Parses a simple HTML table
 pTable :: PandocMonad m
diff --git a/src/Text/Pandoc/Readers/JATS.hs b/src/Text/Pandoc/Readers/JATS.hs
--- a/src/Text/Pandoc/Readers/JATS.hs
+++ b/src/Text/Pandoc/Readers/JATS.hs
@@ -38,6 +38,7 @@
 import qualified Data.Set as S (fromList, member)
 import Data.Set ((\\))
 import Text.Pandoc.Sources (ToSources(..), sourcesToText)
+import Safe (headMay)
 
 type JATS m = StateT JATSState m
 
@@ -300,14 +301,19 @@
                                            _      -> filterChildren isColspec e'
                       let isRow x = named "row" x || named "tr" x
 
-                      -- list of header cell elements
-                      let headRowElements = case filterChild (named "thead") e' of
-                                      Just h -> maybe [] parseElement (filterChild isRow h)
-                                      Nothing -> []
+                      let parseRows elementWithRows =
+                            map parseElement $ filterChildren isRow elementWithRows
+
                       -- list of list of body cell elements
-                      let bodyRowElements = case filterChild (named "tbody") e' of
-                                      Just b -> map parseElement $ filterChildren isRow b
-                                      Nothing -> map parseElement $ filterChildren isRow e'
+                      let multipleBodyRowElements =
+                            map parseRows $ filterChildren (named "tbody") e'
+
+                      -- list of list header cell elements
+                      let headRowElements = maybe [] parseRows (filterChild (named "thead") e')
+
+                      -- list of foot cell elements
+                      let footRowElements = maybe [] parseRows (filterChild (named "tfoot") e')
+
                       let toAlignment c = case findAttr (unqual "align") c of
                                                 Just "left"   -> AlignLeft
                                                 Just "right"  -> AlignRight
@@ -321,7 +327,8 @@
                             w <- findAttr (unqual "colwidth") c
                             n <- safeRead $ "0" <> T.filter (\x -> isDigit x || x == '.') w
                             if n > 0 then Just n else Nothing
-                      let numrows = foldl' max 0 $ map length bodyRowElements
+                      let firstBody = fromMaybe [] (headMay multipleBodyRowElements)
+                      let numrows = foldl' max 0 $ map length firstBody
                       let aligns = case colspecs of
                                      [] -> replicate numrows AlignDefault
                                      cs -> map toAlignment cs
@@ -332,7 +339,6 @@
                                                 Just ws' -> let tot = sum ws'
                                                             in  ColWidth . (/ tot) <$> ws'
                                                 Nothing  -> replicate numrows ColWidthDefault
-
                       let parseCell = parseMixed plain . elContent
                       let elementToCell element = cell
                             (toAlignment element)
@@ -341,15 +347,17 @@
                             <$> (parseCell element)
                       let rowElementsToCells elements = mapM elementToCell elements
                       let toRow = fmap (Row nullAttr) . rowElementsToCells
-                          toHeaderRow element = sequence $ [toRow element | not (null element)]
+                          toRows elements = mapM toRow elements
 
-                      headerRow <- toHeaderRow headRowElements
-                      bodyRows <- mapM toRow bodyRowElements
+                      headerRows <- toRows headRowElements
+                      footerRows <- toRows footRowElements
+                      bodyRows <- mapM toRows multipleBodyRowElements
+
                       return $ table (simpleCaption $ plain capt)
                                      (zip aligns widths)
-                                     (TableHead nullAttr headerRow)
-                                     [TableBody nullAttr 0 [] bodyRows]
-                                     (TableFoot nullAttr [])
+                                     (TableHead nullAttr headerRows)
+                                     (map (TableBody nullAttr 0 []) bodyRows)
+                                     (TableFoot nullAttr footerRows)
          isEntry x  = named "entry" x || named "td" x || named "th" x
          parseElement = filterChildren isEntry
          wrapWithHeader n mBlocks = do
@@ -448,8 +456,12 @@
 parseRefList :: PandocMonad m => Element -> JATS m Blocks
 parseRefList e = do
   refs <- mapM parseRef $ filterChildren (named "ref") e
+  let mbtitle = filterChild (named "title") e
+  title <- case mbtitle of
+    Nothing -> pure mempty
+    Just te -> header 1 <$> parseInline (Elem te)
   addMeta "references" refs
-  return mempty
+  return $ title <> divWith ("refs",[],[]) mempty
 
 parseRef :: PandocMonad m
          => Element -> JATS m (Map.Map Text MetaValue)
diff --git a/src/Text/Pandoc/Readers/LaTeX.hs b/src/Text/Pandoc/Readers/LaTeX.hs
--- a/src/Text/Pandoc/Readers/LaTeX.hs
+++ b/src/Text/Pandoc/Readers/LaTeX.hs
@@ -213,7 +213,7 @@
    let kvs = map replaceTextwidth
              $ filter (\(k,_) -> k `elem` ["width", "height"]) options
    let attr = ("",[], kvs)
-   let alt = str "image"
+   let alt = maybe (str "image") str $ lookup "alt" options
    defaultExt <- getOption readerDefaultImageExtension
    let exts' = [".pdf", ".png", ".jpg", ".mps", ".jpeg", ".jbig2", ".jb2"]
    let exts  = exts' ++ map (map toUpper) exts'
@@ -1171,9 +1171,7 @@
   innerContent <- many $ try (Left <$> label) <|> (Right <$> block)
   let content = walk go $ mconcat $ snd $ partitionEithers innerContent
   st <- getState
-  let caption' = case sCaption st of
-                   Nothing   -> B.emptyCaption
-                   Just capt -> capt
+  let caption' = fromMaybe B.emptyCaption $ sCaption st
   let mblabel  = sLastLabel st
   let attr     = case mblabel of
                    Just lab -> (lab, [], [])
@@ -1190,7 +1188,7 @@
 
   where
   -- Remove the `Image` caption b.c. it's on the `Figure`
-  go (Para [Image attr _ target]) = Plain [Image attr [] target]
+  go (Para [Image attr [Str "image"] target]) = Plain [Image attr [] target]
   go x = x
 
 coloredBlock :: PandocMonad m => Text -> LP m Blocks
diff --git a/src/Text/Pandoc/Readers/Textile.hs b/src/Text/Pandoc/Readers/Textile.hs
--- a/src/Text/Pandoc/Readers/Textile.hs
+++ b/src/Text/Pandoc/Readers/Textile.hs
@@ -40,6 +40,7 @@
 import Data.Char (digitToInt, isUpper)
 import Data.List (intersperse, transpose, foldl')
 import Data.List.NonEmpty (NonEmpty(..), nonEmpty)
+import qualified Data.Map as M
 import Data.Text (Text)
 import qualified Data.Text as T
 import Text.HTML.TagSoup (Tag (..), fromAttrib)
@@ -49,6 +50,7 @@
 import Text.Pandoc.Class.PandocMonad (PandocMonad (..))
 import Text.Pandoc.CSS
 import Text.Pandoc.Definition
+import Text.Pandoc.Logging
 import Text.Pandoc.Options
 import Text.Pandoc.Parsing
 import Text.Pandoc.Readers.HTML (htmlTag, isBlockTag, isInlineTag)
@@ -79,7 +81,7 @@
   -- docMinusKeys is the raw document with blanks where the keys/notes were...
   let firstPassParser = do
         pos <- getPosition
-        t <- noteBlock <|> lineClump
+        t <- noteBlock <|> referenceKey <|> lineClump
         return (pos, t)
   manyTill firstPassParser eof >>= setInput . Sources
   setPosition startPos
@@ -109,6 +111,27 @@
   -- return blanks so line count isn't affected
   return $ T.replicate (sourceLine endPos - sourceLine startPos) "\n"
 
+referenceKey :: PandocMonad m => TextileParser m Text
+referenceKey = try $ do
+  pos <- getPosition
+  char '['
+  refName <- T.pack <$> many1Till nonspaceChar (char ']')
+  refDestination <- T.pack <$> many1Till anyChar newline
+  st <- getState
+  let oldKeys = stateKeys st
+  let key = toKey refName
+  -- Textile doesn't support link titles on the reference
+  -- definition, so use the empty string
+  let target = (refDestination, "")
+  case M.lookup key oldKeys of
+    Just (t, _) | not (t == target) ->
+      -- similar to Markdown, only warn when the targets
+      -- for matching named references differ
+      logMessage $ DuplicateLinkReference refName pos
+    _ -> return ()
+  updateState $ \s -> s {stateKeys = M.insert key (target, nullAttr) oldKeys }
+  return "\n"
+
 -- | Parse document blocks
 parseBlocks :: PandocMonad m => TextileParser m Blocks
 parseBlocks = mconcat <$> manyTill block eof
@@ -624,7 +647,11 @@
                 else lookAhead $ space <|> eof' <|> oneOf "[]" <|>
                        try (oneOf "!.,;:*" *>
                               (space <|> newline <|> eof'))
-  T.pack <$> many1Till nonspaceChar stop
+  rawLink <- T.pack <$> many1Till nonspaceChar stop
+  st <- getState
+  return $ case M.lookup (toKey rawLink) (stateKeys st) of
+    Nothing -> rawLink
+    Just ((src, _), _) -> src
 
 -- | image embedding
 image :: PandocMonad m => TextileParser m Inlines
diff --git a/src/Text/Pandoc/Writers/ChunkedHTML.hs b/src/Text/Pandoc/Writers/ChunkedHTML.hs
--- a/src/Text/Pandoc/Writers/ChunkedHTML.hs
+++ b/src/Text/Pandoc/Writers/ChunkedHTML.hs
@@ -40,6 +40,9 @@
 import Data.List (isInfixOf)
 import Text.Pandoc.Walk (walkM)
 import Text.Pandoc.Builder (setMeta)
+import Text.Pandoc.Templates (compileTemplate, WithDefaultPartials(..))
+import Control.Monad.Except (throwError)
+import Text.Pandoc.Error
 
 -- | Splits document into HTML chunks, dividing them by section,
 -- and returns a zip archive of a folder of files.
@@ -82,10 +85,19 @@
   let Node secinfo secs = chunkedTOC chunkedDoc
   let tocTree = Node secinfo{ secTitle = docTitle meta,
                               secPath = "index.html" } secs
+  let tree = buildTOC opts tocTree
   renderedTOC <- writeHtml5String opts{ writerTemplate = Nothing }
-                    (Pandoc nullMeta [buildTOC opts tocTree])
+                    (Pandoc nullMeta [tree])
+  -- see #8915 -- we need to set the math variable in the top chunk:
+  res <- runWithDefaultPartials $ compileTemplate "mathvar" "$math$"
+  mathVar <- case res of
+    Left e   -> throwError $ PandocTemplateError (T.pack e)
+    Right t  -> return t
+  tocMathVariable <- writeHtml5String opts{ writerTemplate = Just mathVar }
+                    (Pandoc nullMeta [tree])
   let opts' = opts{ writerVariables =
                         defField "table-of-contents" renderedTOC
+                      . defField "math" tocMathVariable
                       $ writerVariables opts }
   entries <- mapM (chunkToEntry opts' meta topChunk) (topChunk : chunks)
   let sitemap = toEntry "sitemap.json" epochtime
diff --git a/src/Text/Pandoc/Writers/Docx.hs b/src/Text/Pandoc/Writers/Docx.hs
--- a/src/Text/Pandoc/Writers/Docx.hs
+++ b/src/Text/Pandoc/Writers/Docx.hs
@@ -124,6 +124,7 @@
           -> m BL.ByteString
 writeDocx opts doc = do
   let Pandoc meta blocks = walk fixDisplayMath doc
+  setupTranslations meta
   let blocks' = makeSections True Nothing blocks
   let doc' = Pandoc meta blocks'
 
@@ -768,7 +769,11 @@
   abstract <- if null abstract'
                  then return []
                  else do
-                   abstractTitle <- translateTerm Abstract
+                   abstractTitle <- case lookupMeta "abstract-title" meta of
+                       Just (MetaBlocks bs)   -> pure $ stringify bs
+                       Just (MetaInlines ils) -> pure $ stringify ils
+                       Just (MetaString s)    -> pure s
+                       _                      -> translateTerm Abstract
                    abstractTit <- withParaPropM (pStyleM "AbstractTitle") $
                                    blocksToOpenXML opts
                                      [Para [Str abstractTitle]]
diff --git a/src/Text/Pandoc/Writers/JATS.hs b/src/Text/Pandoc/Writers/JATS.hs
--- a/src/Text/Pandoc/Writers/JATS.hs
+++ b/src/Text/Pandoc/Writers/JATS.hs
@@ -26,7 +26,6 @@
 import Control.Monad.Reader
 import Control.Monad.State
 import Data.Generics (everywhere, mkT)
-import Data.List (partition)
 import qualified Data.Map as M
 import Data.Maybe (fromMaybe, listToMaybe)
 import Data.Time (toGregorian, Day, parseTimeM, defaultTimeLocale, formatTime)
@@ -94,27 +93,33 @@
 
 -- | Convert Pandoc document to string in JATS format.
 docToJATS :: PandocMonad m => WriterOptions -> Pandoc -> JATS m Text
-docToJATS opts (Pandoc meta blocks) = do
-  let isBackBlock (Div ("refs",_,_) _) = True
-      isBackBlock _                    = False
-  let (backblocks, bodyblocks) = partition isBackBlock blocks
+docToJATS opts (Pandoc meta blocks') = do
   -- The numbering here follows LaTeX's internal numbering
   let startLvl = case writerTopLevelDivision opts of
                    TopLevelPart    -> -1
                    TopLevelChapter -> 0
                    TopLevelSection -> 1
                    TopLevelDefault -> 1
-  let fromBlocks = blocksToJATS opts . makeSections False (Just startLvl)
+  let blocks = makeSections (writerNumberSections opts) (Just startLvl) blocks'
+  let splitBackBlocks b@(Div ("refs",_,_) _) (fs, bs) = (fs, b:bs)
+      splitBackBlocks (Div (ident,("section":_),_)
+                               [ Header lev (_,hcls,hkvs) hils
+                               , (Div rattrs@("refs",_,_) rs)
+                               ]) (fs, bs)
+                       = (fs, Div rattrs
+                               (Header lev (ident,hcls,hkvs) hils : rs) : bs)
+      splitBackBlocks b (fs, bs) = (b:fs, bs)
+  let (bodyblocks, backblocks) = foldr splitBackBlocks ([],[]) blocks
   let colwidth = if writerWrapText opts == WrapAuto
                     then Just $ writerColumns opts
                     else Nothing
   metadata <- metaToContext opts
-                 fromBlocks
+                 (blocksToJATS opts)
                  (fmap chomp . inlinesToJATS opts)
                  meta
-  main <- fromBlocks bodyblocks
+  main <- blocksToJATS opts bodyblocks
   notes <- gets (reverse . map snd . jatsNotes)
-  backs <- fromBlocks backblocks
+  backs <- blocksToJATS opts backblocks
   tagSet <- asks jatsTagSet
   -- In the "Article Authoring" tag set, occurrence of fn-group elements
   -- is restricted to table footers. Footnotes have to be placed inline.
@@ -252,14 +257,21 @@
 
 -- | Convert a Pandoc block element to JATS.
 blockToJATS :: PandocMonad m => WriterOptions -> Block -> JATS m (Doc Text)
-blockToJATS opts (Div (id',"section":_,kvs) (Header _lvl _ ils : xs)) = do
+blockToJATS opts (Div (id',"section":_,kvs) (Header _lvl (_,_,hkvs) ils : xs)) = do
   let idAttr = [ ("id", writerIdentifierPrefix opts <> escapeNCName id')
                | not (T.null id')]
   let otherAttrs = ["sec-type", "specific-use"]
   let attribs = idAttr ++ [(k,v) | (k,v) <- kvs, k `elem` otherAttrs]
   title' <- inlinesToJATS opts (map fixLineBreak ils)
+  let label = if writerNumberSections opts
+                 then
+                   case lookup "number" hkvs of
+                     Just num -> inTagsSimple "label" (literal num)
+                     Nothing -> mempty
+                 else mempty
   contents <- blocksToJATS opts xs
   return $ inTags True "sec" attribs $
+      label $$
       inTagsSimple "title" title' $$ contents
 -- Bibliography reference:
 blockToJATS opts (Div (ident,_,_) [Para lst]) | "ref-" `T.isPrefixOf` ident =
diff --git a/src/Text/Pandoc/Writers/LaTeX/Util.hs b/src/Text/Pandoc/Writers/LaTeX/Util.hs
--- a/src/Text/Pandoc/Writers/LaTeX/Util.hs
+++ b/src/Text/Pandoc/Writers/LaTeX/Util.hs
@@ -104,7 +104,7 @@
          '`' | ctx == CodeString -> emitcseq "\\textasciigrave"
          '$' | not isUrl -> emits "\\$"
          '%' -> emits "\\%"
-         '&' -> emits "\\&"
+         '&' | not isUrl -> emits "\\&"
          '_' | not isUrl -> emits "\\_"
          '#' -> emits "\\#"
          '-' | not isUrl -> case xs of
diff --git a/src/Text/Pandoc/Writers/MediaWiki.hs b/src/Text/Pandoc/Writers/MediaWiki.hs
--- a/src/Text/Pandoc/Writers/MediaWiki.hs
+++ b/src/Text/Pandoc/Writers/MediaWiki.hs
@@ -697,6 +697,7 @@
   "ex",
   "exs",
   "ezhil",
+  "f#",
   "factor",
   "fan",
   "fancy",
diff --git a/test/Tests/MediaBag.hs b/test/Tests/MediaBag.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests/MediaBag.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Tests.MediaBag (tests) where
+
+import Test.Tasty
+import Test.Tasty.HUnit
+-- import Tests.Helpers
+import Text.Pandoc.Class.IO (extractMedia)
+import Text.Pandoc.Class (fillMediaBag, runIOorExplode)
+import System.IO.Temp (withTempDirectory)
+import Text.Pandoc.Shared (inDirectory)
+import System.FilePath
+import Text.Pandoc.Builder as B
+import System.Directory (doesFileExist, copyFile)
+
+tests :: [TestTree]
+tests = [
+  testCase "test fillMediaBag & extractMedia" $
+      withTempDirectory "." "extractMediaTest" $ \tmpdir -> inDirectory tmpdir $ do
+        copyFile "../../test/lalune.jpg" "moon.jpg"
+        let d = B.doc $
+                  B.para (B.image "../../test/lalune.jpg" "" mempty) <>
+                  B.para (B.image "moon.jpg" "" mempty) <>
+                  B.para (B.image "data://image/png;base64,cHJpbnQgImhlbGxvIgo=;.lua+%2f%2e%2e%2f%2e%2e%2fa%2elua" "" mempty) <>
+                  B.para (B.image "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" "" mempty)
+        runIOorExplode $ do
+          fillMediaBag d
+          extractMedia "foo" d
+        exists1 <- doesFileExist ("foo" </> "moon.jpg")
+        assertBool "file in directory is not extracted with original name" exists1
+        exists2 <- doesFileExist ("foo" </> "f9d88c3dbe18f6a7f5670e994a947d51216cdf0e.jpg")
+        assertBool "file above directory is not extracted with hashed name" exists2
+        exists3 <- doesFileExist ("foo" </> "2a0eaa89f43fada3e6c577beea4f2f8f53ab6a1d.lua")
+        exists4 <- doesFileExist "a.lua"
+        assertBool "data uri with malicious payload gets written outside of destination dir"
+          (exists3 && not exists4)
+        exists5 <- doesFileExist ("foo" </> "d5fceb6532643d0d84ffe09c40c481ecdf59e15a.gif")
+        assertBool "data uri with gif is not properly decoded" exists5
+  ]
diff --git a/test/Tests/Readers/DokuWiki.hs b/test/Tests/Readers/DokuWiki.hs
--- a/test/Tests/Readers/DokuWiki.hs
+++ b/test/Tests/Readers/DokuWiki.hs
@@ -167,10 +167,10 @@
               para (imageWith ("", ["align-center"], []) "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
             , "Image with width" =:
               "{{wiki:dokuwiki-128.png?50}}" =?>
-              para (imageWith ("", [], [("width", "50")]) "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
+              para (imageWith ("", [], [("width", "50"), ("query", "?50")]) "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
             , "Image with width and height" =:
               "{{wiki:dokuwiki-128.png?nocache&50x100}}" =?>
-              para (imageWith ("", [], [("width", "50"), ("height", "100")]) "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
+              para (imageWith ("", [], [("width", "50"), ("height", "100"), ("query", "?nocache&50x100")]) "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
             , "Linkonly" =:
               "{{wiki:dokuwiki-128.png?linkonly}}" =?>
               para (link "/wiki/dokuwiki-128.png" "" (str "dokuwiki-128.png"))
diff --git a/test/command/6350.md b/test/command/6350.md
new file mode 100644
--- /dev/null
+++ b/test/command/6350.md
@@ -0,0 +1,29 @@
+```
+% pandoc -f commonmark+implicit_figures -t native
+![caption](image.jpg){#ident width="100%"}
+^D
+[ Para
+    [ Image
+        ( "" , [] , [] ) [ Str "caption" ] ( "image.jpg" , "" )
+    , Str "{#ident"
+    , Space
+    , Str "width=\"100%\"}"
+    ]
+]
+
+```
+
+```
+% pandoc -f commonmark -t native
+![caption](image.jpg){#ident width="100%"}
+^D
+[ Para
+    [ Image
+        ( "" , [] , [] ) [ Str "caption" ] ( "image.jpg" , "" )
+    , Str "{#ident"
+    , Space
+    , Str "width=\"100%\"}"
+    ]
+]
+
+```
diff --git a/test/command/8364.md b/test/command/8364.md
new file mode 100644
--- /dev/null
+++ b/test/command/8364.md
@@ -0,0 +1,54 @@
+```
+% pandoc --citeproc -t jats -s
+---
+reference-section-title: Bibliography
+csl: command/apa.csl
+references:
+- author:
+  - family: Doe
+    given: John
+  id: test
+  issued:
+    date-parts:
+    - - 2006
+  title: Test
+  type: 'article-journal'
+  volume: 81
+---
+
+@test
+^D
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.2 20190208//EN"
+                  "JATS-archivearticle1.dtd">
+<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="1.2" article-type="other">
+<front>
+<journal-meta>
+<journal-id></journal-id>
+<journal-title-group>
+</journal-title-group>
+<issn></issn>
+<publisher>
+<publisher-name></publisher-name>
+</publisher>
+</journal-meta>
+<article-meta>
+<permissions>
+</permissions>
+</article-meta>
+</front>
+<body>
+<p>Doe (2006)</p>
+</body>
+<back>
+<ref-list>
+  <title>Bibliography</title>
+  <ref id="ref-test">
+    <mixed-citation>Doe, J. (2006). Test,
+    <italic>81</italic>.</mixed-citation>
+  </ref>
+</ref-list>
+</back>
+</article>
+
+```
diff --git a/test/command/8365.md b/test/command/8365.md
new file mode 100644
--- /dev/null
+++ b/test/command/8365.md
@@ -0,0 +1,50 @@
+```
+% pandoc -f jats -t native -s
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.2 20190208//EN"
+                  "JATS-archivearticle1.dtd">
+<article xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" dtd-version="1.2" article-type="other">
+<front>
+<journal-meta>
+<journal-id></journal-id>
+<journal-title-group>
+</journal-title-group>
+<issn></issn>
+<publisher>
+<publisher-name></publisher-name>
+</publisher>
+</journal-meta>
+<article-meta>
+<permissions>
+</permissions>
+</article-meta>
+</front>
+<body>
+<p>Doe (2006)</p>
+</body>
+<back>
+<ref-list>
+  <title>Bibliography</title>
+  <ref id="ref-test">
+    <mixed-citation>Doe, J. (2006). Test,
+    <italic>81</italic>.</mixed-citation>
+  </ref>
+</ref-list>
+</back>
+</article>
+^D
+Pandoc
+  Meta
+    { unMeta =
+        fromList
+          [ ( "references"
+            , MetaList
+                [ MetaMap (fromList [ ( "id" , MetaString "test" ) ]) ]
+            )
+          ]
+    }
+  [ Para [ Str "Doe" , Space , Str "(2006)" ]
+  , Header 1 ( "" , [] , [] ) [ Str "Bibliography" ]
+  , Div ( "refs" , [] , [] ) []
+  ]
+```
diff --git a/test/command/8745.md b/test/command/8745.md
new file mode 100644
--- /dev/null
+++ b/test/command/8745.md
@@ -0,0 +1,52 @@
+# Alt text on images
+
+```
+% pandoc -f latex -t native
+\documentclass[12pt]{article}
+\usepackage{graphicx}
+\begin{document}
+Sample text
+\begin{figure}[ht]
+    \includegraphics[alt={Upside down painting},width=0.5\textwidth]{New_York_City_I.jpg}
+    \caption{New York City by Piet Mondrian (Wikipedia)}
+    \label{fig:Mondrian}
+\end{figure}
+\includegraphics[alt={Face of a mandrill}]{mandrill.jpg}
+\end{document}
+^D
+[ Para [ Str "Sample" , Space , Str "text" ]
+, Figure
+    ( "fig:Mondrian" , [] , [] )
+    (Caption
+       Nothing
+       [ Plain
+           [ Str "New"
+           , Space
+           , Str "York"
+           , Space
+           , Str "City"
+           , Space
+           , Str "by"
+           , Space
+           , Str "Piet"
+           , Space
+           , Str "Mondrian"
+           , Space
+           , Str "(Wikipedia)"
+           ]
+       ])
+    [ Para
+        [ Image
+            ( "" , [] , [ ( "width" , "50%" ) ] )
+            [ Str "Upside down painting" ]
+            ( "New_York_City_I.jpg" , "" )
+        ]
+    ]
+, Para
+    [ Image
+        ( "" , [] , [] )
+        [ Str "Face of a mandrill" ]
+        ( "mandrill.jpg" , "" )
+    ]
+]
+```
diff --git a/test/command/8764.md b/test/command/8764.md
--- a/test/command/8764.md
+++ b/test/command/8764.md
@@ -21,7 +21,7 @@
   <table:table-column table:style-name="Table1.C" />
   <table:table-row>
     <table:table-cell table:style-name="TableRowCell" office:value-type="string">
-      <text:p text:style-name="Table_20_Heading">Header</text:p>
+      <text:p text:style-name="Table_20_Contents">Header</text:p>
     </table:table-cell>
     <table:table-cell table:style-name="TableRowCell" office:value-type="string">
       <text:p text:style-name="Table_20_Contents">Normal cell (column
@@ -34,7 +34,7 @@
   </table:table-row>
   <table:table-row>
     <table:table-cell table:style-name="TableRowCell" office:value-type="string">
-      <text:p text:style-name="Table_20_Heading">Normal cell (column
+      <text:p text:style-name="Table_20_Contents">Normal cell (column
       1)</text:p>
     </table:table-cell>
     <table:table-cell table:style-name="TableRowCell" office:value-type="string">
diff --git a/test/html-reader.html b/test/html-reader.html
--- a/test/html-reader.html
+++ b/test/html-reader.html
@@ -524,6 +524,34 @@
         <td>2</td>
         <td>3</td>
     </tr>
+    <tr>
+        <td colspan="3">Details</td>
+    </tr>
+    </tbody>
+    <tfoot>
+    <tr>
+        <th>4</th>
+        <td>5</td>
+        <td>6</td>
+    </tr>
+    </tfoot>
+</table>
+<hr />
+<table>
+    <tbody>
+    <tr>
+        <th>X</th>
+        <th>Y</th>
+        <th>Z</th>
+    </tr>
+    <tr>
+        <td>1</td>
+        <td>2</td>
+        <td>3</td>
+    </tr>
+    <tr>
+        <td colspan="3">Details</td>
+    </tr>
     </tbody>
     <tfoot>
     <tr>
diff --git a/test/html-reader.native b/test/html-reader.native
--- a/test/html-reader.native
+++ b/test/html-reader.native
@@ -2262,7 +2262,7 @@
          ])
       [ TableBody
           ( "" , [] , [] )
-          (RowHeadColumns 1)
+          (RowHeadColumns 0)
           []
           [ Row
               ( "" , [] , [] )
@@ -2284,6 +2284,105 @@
                   (RowSpan 1)
                   (ColSpan 1)
                   [ Plain [ Str "3" ] ]
+              ]
+          , Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 3)
+                  [ Plain [ Str "Details" ] ]
+              ]
+          ]
+      ]
+      (TableFoot
+         ( "" , [] , [] )
+         [ Row
+             ( "" , [] , [] )
+             [ Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Plain [ Str "4" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Plain [ Str "5" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Plain [ Str "6" ] ]
+             ]
+         ])
+  , HorizontalRule
+  , Table
+      ( "" , [] , [] )
+      (Caption Nothing [])
+      [ ( AlignDefault , ColWidthDefault )
+      , ( AlignDefault , ColWidthDefault )
+      , ( AlignDefault , ColWidthDefault )
+      ]
+      (TableHead ( "" , [] , [] ) [])
+      [ TableBody
+          ( "" , [] , [] )
+          (RowHeadColumns 0)
+          [ Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "X" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "Y" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "Z" ] ]
+              ]
+          ]
+          [ Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "1" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "2" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Plain [ Str "3" ] ]
+              ]
+          , Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 3)
+                  [ Plain [ Str "Details" ] ]
               ]
           ]
       ]
diff --git a/test/jats-reader.native b/test/jats-reader.native
--- a/test/jats-reader.native
+++ b/test/jats-reader.native
@@ -2427,6 +2427,27 @@
                  AlignDefault
                  (RowSpan 1)
                  (ColSpan 1)
+                 [ Para [ Str "r1a" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "r1b" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "r1c" ] ]
+             ]
+         , Row
+             ( "" , [] , [] )
+             [ Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
                  [ Para [ Str "X" ] ]
              , Cell
                  ( "" , [] , [] )
@@ -2894,6 +2915,163 @@
                   (RowSpan 1)
                   (ColSpan 2)
                   [ Para [ Str "7" ] ]
+              ]
+          ]
+      ]
+      (TableFoot ( "" , [] , [] ) [])
+  , Header
+      2
+      ( "table-with-footer" , [] , [] )
+      [ Str "Table" , Space , Str "with" , Space , Str "footer" ]
+  , Table
+      ( "" , [] , [] )
+      (Caption Nothing [])
+      [ ( AlignLeft , ColWidthDefault )
+      , ( AlignLeft , ColWidthDefault )
+      , ( AlignLeft , ColWidthDefault )
+      ]
+      (TableHead ( "" , [] , [] ) [])
+      [ TableBody
+          ( "" , [] , [] )
+          (RowHeadColumns 0)
+          []
+          [ Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "1" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "2" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "3" ] ]
+              ]
+          ]
+      ]
+      (TableFoot
+         ( "" , [] , [] )
+         [ Row
+             ( "" , [] , [] )
+             [ Cell
+                 ( "" , [] , [] )
+                 AlignRight
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f1" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f2" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f3" ] ]
+             ]
+         , Row
+             ( "" , [] , [] )
+             [ Cell
+                 ( "" , [] , [] )
+                 AlignRight
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f4" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f5" ] ]
+             , Cell
+                 ( "" , [] , [] )
+                 AlignDefault
+                 (RowSpan 1)
+                 (ColSpan 1)
+                 [ Para [ Str "f6" ] ]
+             ]
+         ])
+  , Header
+      2
+      ( "table-with-multiple-bodies" , [] , [] )
+      [ Str "Table"
+      , Space
+      , Str "With"
+      , Space
+      , Str "Multiple"
+      , Space
+      , Str "Bodies"
+      ]
+  , Table
+      ( "" , [] , [] )
+      (Caption Nothing [])
+      [ ( AlignLeft , ColWidthDefault )
+      , ( AlignLeft , ColWidthDefault )
+      , ( AlignLeft , ColWidthDefault )
+      ]
+      (TableHead ( "" , [] , [] ) [])
+      [ TableBody
+          ( "" , [] , [] )
+          (RowHeadColumns 0)
+          []
+          [ Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignRight
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "a1" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "a2" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "a3" ] ]
+              ]
+          ]
+      , TableBody
+          ( "" , [] , [] )
+          (RowHeadColumns 0)
+          []
+          [ Row
+              ( "" , [] , [] )
+              [ Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "b1" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "b2" ] ]
+              , Cell
+                  ( "" , [] , [] )
+                  AlignDefault
+                  (RowSpan 1)
+                  (ColSpan 1)
+                  [ Para [ Str "b3" ] ]
               ]
           ]
       ]
diff --git a/test/jats-reader.xml b/test/jats-reader.xml
--- a/test/jats-reader.xml
+++ b/test/jats-reader.xml
@@ -961,6 +961,17 @@
       <thead>
         <tr>
           <th>
+            <p>r1a</p>
+          </th>
+          <th>
+            <p>r1b</p>
+          </th>
+          <th>
+            <p>r1c</p>
+          </th>
+        </tr>
+        <tr>
+          <th>
             <p>X</p>
           </th>
           <th>
@@ -1198,6 +1209,85 @@
         <td colspan="2">
             <p>7</p>
         </td>
+        </tr>
+      </tbody>
+    </table>
+  </sec>
+  <sec id="table-with-footer">
+    <title>Table with footer</title>
+    <table>
+      <col align="left" />
+      <col align="left" />
+      <col align="left" />
+      <tbody>
+        <tr>
+          <td>
+            <p>1</p>
+          </td>
+          <td>
+            <p>2</p>
+          </td>
+          <td>
+            <p>3</p>
+          </td>
+        </tr>
+      </tbody>
+      <tfoot>
+        <tr>
+          <td align="right">
+            <p>f1</p>
+          </td>
+          <td>
+            <p>f2</p>
+          </td>
+          <td>
+            <p>f3</p>
+          </td>
+        </tr>
+        <tr>
+          <td align="right">
+            <p>f4</p>
+          </td>
+          <td>
+            <p>f5</p>
+          </td>
+          <td>
+            <p>f6</p>
+          </td>
+        </tr>
+      </tfoot>
+    </table>
+  </sec>
+  <sec id="table-with-multiple-bodies">
+    <title>Table With Multiple Bodies</title>
+    <table>
+      <col align="left" />
+      <col align="left" />
+      <col align="left" />
+      <tbody>
+        <tr>
+          <td align="right">
+            <p>a1</p>
+          </td>
+          <td>
+            <p>a2</p>
+          </td>
+          <td>
+            <p>a3</p>
+          </td>
+        </tr>
+      </tbody>
+      <tbody>
+        <tr>
+          <td>
+            <p>b1</p>
+          </td>
+          <td>
+            <p>b2</p>
+          </td>
+          <td>
+            <p>b3</p>
+          </td>
         </tr>
       </tbody>
     </table>
diff --git a/test/test-pandoc.hs b/test/test-pandoc.hs
--- a/test/test-pandoc.hs
+++ b/test/test-pandoc.hs
@@ -50,6 +50,7 @@
 import qualified Tests.Writers.AnnotatedTable
 import qualified Tests.Writers.TEI
 import qualified Tests.Writers.Markua
+import qualified Tests.MediaBag
 import Text.Pandoc.Shared (inDirectory)
 
 tests :: FilePath -> TestTree
@@ -57,6 +58,7 @@
         [ Tests.Command.tests
         , testGroup "Old" (Tests.Old.tests pandocPath)
         , testGroup "Shared" Tests.Shared.tests
+        , testGroup "MediaBag" Tests.MediaBag.tests
         , testGroup "Writers"
           [ testGroup "Native" Tests.Writers.Native.tests
           , testGroup "ConTeXt" Tests.Writers.ConTeXt.tests
diff --git a/test/textile-reader.native b/test/textile-reader.native
--- a/test/textile-reader.native
+++ b/test/textile-reader.native
@@ -749,6 +749,33 @@
       , Space
       , Str "spaces."
       ]
+  , Para
+      [ Str "A"
+      , Space
+      , Link
+          ( "" , [] , [] ) [ Str "link" ] ( "ftp://example.com" , "" )
+      , Space
+      , Str "to"
+      , Space
+      , Str "a"
+      , Space
+      , Str "named"
+      , Space
+      , Str "target"
+      ]
+  , Para
+      [ Str "A"
+      , Space
+      , Link ( "" , [] , [] ) [ Str "link" ] ( "missing" , "" )
+      , Space
+      , Str "to"
+      , Space
+      , Str "a"
+      , Space
+      , Str "missing"
+      , Space
+      , Str "target"
+      ]
   , Header 1 ( "tables" , [] , [] ) [ Str "Tables" ]
   , Para
       [ Str "Textile"
diff --git a/test/textile-reader.textile b/test/textile-reader.textile
--- a/test/textile-reader.textile
+++ b/test/textile-reader.textile
@@ -183,6 +183,10 @@
 
 A link["with brackets":http://www.example.com]and no spaces.
 
+A "link":link-target to a named target
+
+A "link":missing to a missing target
+
 h1. Tables
 
 Textile allows tables with and without headers :
@@ -277,3 +281,5 @@
 is here.
 
 not a comment.
+
+[link-target]ftp://example.com
diff --git a/test/writer.latex b/test/writer.latex
--- a/test/writer.latex
+++ b/test/writer.latex
@@ -734,7 +734,7 @@
 `He said, ``I want to go.''\,' Were you alive in the 70's?
 
 Here is some quoted `\texttt{code}' and a
-``\href{http://example.com/?foo=1\&bar=2}{quoted link}''.
+``\href{http://example.com/?foo=1&bar=2}{quoted link}''.
 
 Some dashes: one---two --- three---four --- five.
 
@@ -908,19 +908,19 @@
 \hypertarget{with-ampersands}{%
 \subsection{With ampersands}\label{with-ampersands}}
 
-Here's a \href{http://example.com/?foo=1\&bar=2}{link with an ampersand in the
+Here's a \href{http://example.com/?foo=1&bar=2}{link with an ampersand in the
 URL}.
 
 Here's a link with an amersand in the link text: \href{http://att.com/}{AT\&T}.
 
-Here's an \href{/script?foo=1\&bar=2}{inline link}.
+Here's an \href{/script?foo=1&bar=2}{inline link}.
 
-Here's an \href{/script?foo=1\&bar=2}{inline link in pointy braces}.
+Here's an \href{/script?foo=1&bar=2}{inline link in pointy braces}.
 
 \hypertarget{autolinks}{%
 \subsection{Autolinks}\label{autolinks}}
 
-With an ampersand: \url{http://example.com/?foo=1\&bar=2}
+With an ampersand: \url{http://example.com/?foo=1&bar=2}
 
 \begin{itemize}
 \tightlist
