diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,23 @@
 
 # Releases
 
+## Hakyll 4.15.1.0 (2021-10-25)
+
+- Add `Hakyll.Web.Pandoc.Biblio` functions `readPandocBiblios` and
+    `processPandocBiblios`, which let one use multiple bibliographies
+    (contribution by Benjamin Eskola)
+- Preserve file extension of bibliography files when passing them to Pandoc.
+    This enables one to use not just BibTex, but also YAML and JSON files
+    (contribution by Benjamin Eskola)
+- Fix URL extraction for `srcset` attribute. This affects
+    `Hakyll.Web.HTML.relativizeUrls` and other such functions (contribution by
+    Alexander Batischev)
+- Bump `bytestring` upper bound to allow 0.11 (contribution by Alexander
+    Batischev)
+- Bump `pandoc` upper bound to allow 2.15 (contribution by Alexander Batischev)
+- Bump `aeson` bounds to allow 2.0 (contribution by Alexander Batischev)
+
+
 ## Hakyll 4.15.0.1 (2021-10-02)
 
 - Add missing test file to the package (contribution by Alexander Batischev)
diff --git a/hakyll.cabal b/hakyll.cabal
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -1,5 +1,5 @@
 Name:    hakyll
-Version: 4.15.0.1
+Version: 4.15.1.0
 
 Synopsis: A static website compiler library
 Description:
@@ -59,11 +59,15 @@
 
 Extra-source-files:
   CHANGELOG.md
-  tests/data/biblio/biblio01.golden
   tests/data/biblio/chicago.csl
+  tests/data/biblio/cites-meijer.golden
+  tests/data/biblio/cites-multiple.golden
+  tests/data/biblio/cites-multiple.markdown
   tests/data/biblio/default.html
   tests/data/biblio/page.markdown
   tests/data/biblio/refs.bib
+  tests/data/biblio/refs.yaml
+  tests/data/biblio/refs2.yaml
   tests/data/embed.html
   tests/data/example.md
   tests/data/example.md.metadata
@@ -173,12 +177,12 @@
     Paths_hakyll
 
   Build-Depends:
-    aeson                >= 1.0      && < 1.6,
+    aeson                >= 1.0      && < 1.6 || >= 2.0 && < 2.1,
     base                 >= 4.8      && < 5,
     binary               >= 0.5      && < 0.10,
     blaze-html           >= 0.5      && < 0.10,
     blaze-markup         >= 0.5.1    && < 0.9,
-    bytestring           >= 0.9      && < 0.11,
+    bytestring           >= 0.9      && < 0.12,
     containers           >= 0.3      && < 0.7,
     data-default         >= 0.4      && < 0.8,
     deepseq              >= 1.3      && < 1.5,
@@ -242,7 +246,7 @@
     Other-Modules:
       Hakyll.Web.Pandoc.Binary
     Build-Depends:
-      pandoc >= 2.11 && < 2.15
+      pandoc >= 2.11 && < 2.16
     Cpp-options:
       -DUSE_PANDOC
 
@@ -280,10 +284,12 @@
     tasty-hunit                >= 0.9  && < 0.11,
     tasty-quickcheck           >= 0.8  && < 0.11,
     -- Copy pasted from hakyll dependencies:
+    aeson                >= 1.0      && < 1.6 || >= 2.0 && < 2.1,
     base                 >= 4.8      && < 5,
-    bytestring           >= 0.9      && < 0.11,
+    bytestring           >= 0.9      && < 0.12,
     containers           >= 0.3      && < 0.7,
     filepath             >= 1.0      && < 1.5,
+    tagsoup              >= 0.13.1   && < 0.15,
     text                 >= 0.11     && < 1.3,
     unordered-containers >= 0.2      && < 0.3,
     yaml                 >= 0.8.11   && < 0.12
@@ -338,4 +344,4 @@
     base      >= 4     && < 5,
     directory >= 1.0   && < 1.4,
     filepath  >= 1.0   && < 1.5,
-    pandoc    >= 2.11  && < 2.15
+    pandoc    >= 2.11  && < 2.16
diff --git a/lib/Hakyll/Core/Metadata.hs b/lib/Hakyll/Core/Metadata.hs
--- a/lib/Hakyll/Core/Metadata.hs
+++ b/lib/Hakyll/Core/Metadata.hs
@@ -1,4 +1,5 @@
 --------------------------------------------------------------------------------
+{-# LANGUAGE CPP #-}
 module Hakyll.Core.Metadata
     ( Metadata
     , lookupString
@@ -14,12 +15,16 @@
 
 
 --------------------------------------------------------------------------------
-import           Control.Arrow                  (second)
 import           Control.Monad                  (forM)
 import           Control.Monad.Fail             (MonadFail)
 import           Data.Binary                    (Binary (..), getWord8,
                                                  putWord8, Get)
-import qualified Data.HashMap.Strict            as HMS
+#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson.KeyMap              as KeyMap
+import qualified Data.Aeson.Key                 as AK
+#else
+import qualified Data.HashMap.Strict            as KeyMap
+#endif
 import qualified Data.Set                       as S
 import qualified Data.Text                      as T
 import qualified Data.Vector                    as V
@@ -35,13 +40,13 @@
 
 --------------------------------------------------------------------------------
 lookupString :: String -> Metadata -> Maybe String
-lookupString key meta = HMS.lookup (T.pack key) meta >>= Yaml.toString
+lookupString key meta = KeyMap.lookup (keyFromString key) meta >>= Yaml.toString
 
 
 --------------------------------------------------------------------------------
 lookupStringList :: String -> Metadata -> Maybe [String]
 lookupStringList key meta =
-    HMS.lookup (T.pack key) meta >>= Yaml.toList >>= mapM Yaml.toString
+    KeyMap.lookup (keyFromString key) meta >>= Yaml.toList >>= mapM Yaml.toString
 
 
 --------------------------------------------------------------------------------
@@ -106,7 +111,7 @@
         Yaml.Object obj -> do
             putWord8 0
             let list :: [(T.Text, BinaryYaml)]
-                list = map (second BinaryYaml) $ HMS.toList obj
+                list = map (\(k, v) -> (keyToText k, BinaryYaml v)) $ KeyMap.toList obj
             put list
 
         Yaml.Array arr -> do
@@ -125,7 +130,7 @@
             0 -> do
                 list <- get :: Get [(T.Text, BinaryYaml)]
                 return $ BinaryYaml $ Yaml.Object $
-                    HMS.fromList $ map (second unBinaryYaml) list
+                    KeyMap.fromList $ map (\(k, v) -> (keyFromText k, unBinaryYaml v)) list
 
             1 -> do
                 list <- get :: Get [BinaryYaml]
@@ -137,3 +142,25 @@
             4 -> BinaryYaml . Yaml.Bool   <$> get
             5 -> return $ BinaryYaml Yaml.Null
             _ -> fail "Data.Binary.get: Invalid Binary Metadata"
+
+
+--------------------------------------------------------------------------------
+#if MIN_VERSION_aeson(2,0,0)
+keyFromString :: String -> AK.Key
+keyFromString = AK.fromString
+
+keyToText :: AK.Key -> T.Text
+keyToText = AK.toText
+
+keyFromText :: T.Text -> AK.Key
+keyFromText = AK.fromText
+#else
+keyFromString :: String -> T.Text
+keyFromString = T.pack
+
+keyToText :: T.Text -> T.Text
+keyToText = id
+
+keyFromText :: T.Text -> T.Text
+keyFromText = id
+#endif
diff --git a/lib/Hakyll/Core/Provider/Metadata.hs b/lib/Hakyll/Core/Provider/Metadata.hs
--- a/lib/Hakyll/Core/Provider/Metadata.hs
+++ b/lib/Hakyll/Core/Provider/Metadata.hs
@@ -144,9 +144,9 @@
       where
         hint = case err of
             Yaml.InvalidYaml (Just (Yaml.YamlParseException {..}))
-                | yamlProblem == problem -> "\n" ++
+                | yamlProblem ==  "mapping values are not allowed in this context" -> "\n" ++
                     "Hint: if the metadata value contains characters such\n" ++
                     "as ':' or '-', try enclosing it in quotes."
+            Yaml.AesonException "Error in $: parsing HashMap ~Text failed, expected Object, but encountered String"
+                -> "\nHint: in metadata, keys and values are separated by a colon *and* a space."
             _ -> ""
-
-        problem = "mapping values are not allowed in this context"
diff --git a/lib/Hakyll/Web/Html.hs b/lib/Hakyll/Web/Html.hs
--- a/lib/Hakyll/Web/Html.hs
+++ b/lib/Hakyll/Web/Html.hs
@@ -25,12 +25,17 @@
 --------------------------------------------------------------------------------
 import           Data.Char                       (digitToInt, intToDigit,
                                                   isDigit, toLower)
-import           Data.List                       (isPrefixOf)
+import           Data.Either                     (fromRight)
+import           Data.List                       (isPrefixOf, intercalate)
+import           Data.Maybe                      (fromMaybe)
 import qualified Data.Set                        as S
+import           Control.Monad                   (void)
 import           System.FilePath                 (joinPath, splitPath,
                                                   takeDirectory)
 import           Text.Blaze.Html                 (toHtml)
 import           Text.Blaze.Html.Renderer.String (renderHtml)
+import qualified Text.Parsec                     as P
+import qualified Text.Parsec.Char                as PC
 import qualified Text.HTML.TagSoup               as TS
 import           Network.URI                     (isUnreserved, escapeURIString)
 
@@ -71,12 +76,21 @@
 
 --------------------------------------------------------------------------------
 isUrlAttribute :: String -> Bool
-isUrlAttribute = (`elem` ["src", "href", "data", "poster", "srcset"])
+isUrlAttribute = (`elem` ["src", "href", "data", "poster"])
 
 
 --------------------------------------------------------------------------------
+-- | Extract URLs from tags' attributes. Those would be the same URLs on which
+-- `withUrls` would act.
 getUrls :: [TS.Tag String] -> [String]
-getUrls tags = [v | TS.TagOpen _ as <- tags, (k, v) <- as, isUrlAttribute k]
+getUrls tags = [u | TS.TagOpen _ as <- tags, (k, v) <- as, u <- extractUrls k v]
+  where
+  extractUrls "srcset" value =
+    let srcset = fmap unSrcset $ P.parse srcsetParser "" value
+    in map srcsetImageCandidateUrl $ fromRight [] srcset
+  extractUrls key value
+    | isUrlAttribute key = [value]
+    | otherwise = []
 
 
 --------------------------------------------------------------------------------
@@ -86,6 +100,14 @@
   where
     tag (TS.TagOpen s a) = TS.TagOpen s $ map attr a
     tag x                = x
+
+    attr input@("srcset", v)   =
+      case fmap unSrcset $ P.parse srcsetParser "" v of
+        Right srcset ->
+          let srcset' = map (\i -> i { srcsetImageCandidateUrl = f $ srcsetImageCandidateUrl i }) srcset
+              srcset'' = show $ Srcset srcset'
+          in ("srcset", srcset'')
+        Left _ -> input
     attr (k, v)          = (k, if isUrlAttribute k then f v else v)
 
 
@@ -142,7 +164,7 @@
 --------------------------------------------------------------------------------
 -- | Get the relative url to the site root, for a given (absolute) url
 toSiteRoot :: String -> String
-toSiteRoot = removeWinPathSeparator . emptyException . joinPath 
+toSiteRoot = removeWinPathSeparator . emptyException . joinPath
            . map parent . filter relevant . splitPath . takeDirectory
   where
     parent            = const ".."
@@ -198,3 +220,83 @@
 -- > "Me &amp; Dean"
 escapeHtml :: String -> String
 escapeHtml = renderHtml . toHtml
+
+
+--------------------------------------------------------------------------------
+data Srcset = Srcset {
+    unSrcset :: [SrcsetImageCandidate]
+  }
+
+
+--------------------------------------------------------------------------------
+instance Show Srcset where
+  show set = intercalate ", " $ map show $ unSrcset set
+
+
+--------------------------------------------------------------------------------
+data SrcsetImageCandidate = SrcsetImageCandidate {
+    srcsetImageCandidateUrl :: String
+  , srcsetImageCandidateDescriptor :: Maybe String
+  }
+
+
+--------------------------------------------------------------------------------
+instance Show SrcsetImageCandidate where
+  show candidate =
+    let url = srcsetImageCandidateUrl candidate
+    in case srcsetImageCandidateDescriptor candidate of
+      Just desc -> concat [url, " ", desc]
+      Nothing -> url
+
+
+--------------------------------------------------------------------------------
+-- HTML spec: https://html.spec.whatwg.org/#srcset-attributes
+srcsetParser :: P.Parsec String () Srcset
+srcsetParser = do
+  result <- candidate `P.sepBy1` (PC.char ',')
+  P.eof
+  return $ Srcset result
+  where
+  candidate :: P.Parsec String () SrcsetImageCandidate
+  candidate = do
+    P.skipMany ascii_whitespace
+    u <- url
+    P.skipMany ascii_whitespace
+    desc <- P.optionMaybe $ P.choice $ fmap P.try [width_descriptor, px_density_descriptor]
+    P.skipMany ascii_whitespace
+    return $ SrcsetImageCandidate {
+        srcsetImageCandidateUrl = u
+      , srcsetImageCandidateDescriptor = desc
+      }
+
+  -- This is an over-simplification, but should be good enough for our purposes
+  url :: P.Parsec String () String
+  url = P.many1 $ PC.noneOf " ,"
+
+  ascii_whitespace :: P.Parsec String () ()
+  ascii_whitespace = void $ P.oneOf "\x09\x0A\x0C\x0D\x20"
+
+  width_descriptor :: P.Parsec String () String
+  width_descriptor = do
+    number <- P.many1 PC.digit
+    void $ PC.char 'w'
+    return $ concat [number, "w"]
+
+  px_density_descriptor :: P.Parsec String () String
+  px_density_descriptor = do
+    sign <- P.optionMaybe $ PC.char '-'
+    int <- P.many1 PC.digit
+    frac <- P.optionMaybe $ do
+      void $ PC.char '.'
+      frac <- P.many1 PC.digit
+      return $ concat [".", frac]
+    expon <- P.optionMaybe $ do
+      letter <- P.oneOf "eE"
+      e_sign <- P.optionMaybe $ PC.oneOf "-+"
+      number <- P.many1 PC.digit
+      return $ concat [[letter], mb $ fmap show e_sign, number]
+    void $ PC.char 'x'
+    return $ concat [mb $ fmap show sign, int, mb frac, mb expon, "x"]
+
+  mb :: Maybe String -> String
+  mb = fromMaybe ""
diff --git a/lib/Hakyll/Web/Pandoc/Biblio.hs b/lib/Hakyll/Web/Pandoc/Biblio.hs
--- a/lib/Hakyll/Web/Pandoc/Biblio.hs
+++ b/lib/Hakyll/Web/Pandoc/Biblio.hs
@@ -21,7 +21,9 @@
     , Biblio (..)
     , biblioCompiler
     , readPandocBiblio
+    , readPandocBiblios
     , processPandocBiblio
+    , processPandocBiblios
     , pandocBiblioCompiler
     ) where
 
@@ -33,6 +35,7 @@
 import qualified Data.ByteString.Lazy          as BL
 import qualified Data.Map                      as Map
 import qualified Data.Time                     as Time
+import qualified Data.Text                     as T (pack)
 import           Data.Typeable                 (Typeable)
 import           Hakyll.Core.Compiler
 import           Hakyll.Core.Compiler.Internal
@@ -45,6 +48,7 @@
                                                 enableExtension)
 import qualified Text.Pandoc                   as Pandoc
 import qualified Text.Pandoc.Citeproc          as Pandoc (processCitations)
+import           System.FilePath               (addExtension, takeExtension)
 
 
 --------------------------------------------------------------------------------
@@ -86,9 +90,16 @@
                  -> Item Biblio
                  -> (Item String)
                  -> Compiler (Item Pandoc)
-readPandocBiblio ropt csl biblio item = do
+readPandocBiblio ropt csl biblio = readPandocBiblios ropt csl [biblio]
+
+readPandocBiblios :: ReaderOptions
+                  -> Item CSL
+                  -> [Item Biblio]
+                  -> (Item String)
+                  -> Compiler (Item Pandoc)
+readPandocBiblios ropt csl biblios item = do
   pandoc <- readPandocWith ropt item
-  processPandocBiblio csl biblio pandoc
+  processPandocBiblios csl biblios pandoc
 
 
 --------------------------------------------------------------------------------
@@ -96,7 +107,13 @@
                     -> Item Biblio
                     -> (Item Pandoc)
                     -> Compiler (Item Pandoc)
-processPandocBiblio csl biblio item = do
+processPandocBiblio csl biblio = processPandocBiblios csl [biblio]
+
+processPandocBiblios :: Item CSL
+                     -> [Item Biblio]
+                     -> (Item Pandoc)
+                     -> Compiler (Item Pandoc)
+processPandocBiblios csl biblios item = do
     -- It's not straightforward to use the Pandoc API as of 2.11 to deal with
     -- citations, since it doesn't export many things in 'Text.Pandoc.Citeproc'.
     -- The 'citeproc' package is also hard to use.
@@ -108,16 +125,25 @@
     -- ersatz filesystem.
     let Pandoc.Pandoc (Pandoc.Meta meta) blocks = itemBody item
         cslFile = Pandoc.FileInfo zeroTime . unCSL $ itemBody csl
-        bibFile = Pandoc.FileInfo zeroTime . unBiblio $ itemBody biblio
-        addBiblioFiles = \st -> st
-            { Pandoc.stFiles =
-                Pandoc.insertInFileTree "_hakyll/style.csl" cslFile .
-                Pandoc.insertInFileTree "_hakyll/refs.bib" bibFile $
-                Pandoc.stFiles st
-            }
+        bibFiles = zipWith (\x y ->
+            ( addExtension ("_hakyll/bibliography-" ++ show x)
+                           (takeExtension $ toFilePath $ itemIdentifier y)
+            , Pandoc.FileInfo zeroTime . unBiblio . itemBody $ y
+            )
+          )
+          [0 ..]
+          biblios
+
+        stFiles = foldr ((.) . uncurry Pandoc.insertInFileTree)
+                    (Pandoc.insertInFileTree "_hakyll/style.csl" cslFile)
+                    bibFiles
+
+        addBiblioFiles = \st -> st { Pandoc.stFiles = stFiles $ Pandoc.stFiles st }
+
         biblioMeta = Pandoc.Meta .
             Map.insert "csl" (Pandoc.MetaString "_hakyll/style.csl") .
-            Map.insert "bibliography" (Pandoc.MetaString "_hakyll/refs.bib") $
+            Map.insert "bibliography"
+              (Pandoc.MetaList $ map (Pandoc.MetaString . T.pack . fst) bibFiles) $
             meta
         errOrPandoc = Pandoc.runPure $ do
             Pandoc.modifyPureState addBiblioFiles
diff --git a/lib/Hakyll/Web/Template/Context.hs b/lib/Hakyll/Web/Template/Context.hs
--- a/lib/Hakyll/Web/Template/Context.hs
+++ b/lib/Hakyll/Web/Template/Context.hs
@@ -10,7 +10,7 @@
 -- > … <> functionField "concat" (const . concat) <> …
 --
 -- which will allow you to use the @concat@ identifier as a function that takes
--- arbitrarily many stings and concatenates them to a new string:
+-- arbitrarily many strings and concatenates them to a new string:
 --
 -- > $partial(concat("templates/categories/", category))$
 --
diff --git a/tests/Hakyll/Core/Provider/Metadata/Tests.hs b/tests/Hakyll/Core/Provider/Metadata/Tests.hs
--- a/tests/Hakyll/Core/Provider/Metadata/Tests.hs
+++ b/tests/Hakyll/Core/Provider/Metadata/Tests.hs
@@ -1,12 +1,18 @@
 --------------------------------------------------------------------------------
+{-# LANGUAGE CPP #-}
 module Hakyll.Core.Provider.Metadata.Tests
     ( tests
     ) where
 
 
 --------------------------------------------------------------------------------
-import qualified Data.HashMap.Strict           as HMS
+#if MIN_VERSION_aeson(2,0,0)
+import qualified Data.Aeson.KeyMap             as KeyMap
+import qualified Data.Aeson.Key                as AK
+#else
+import qualified Data.HashMap.Strict           as KeyMap
 import qualified Data.Text                     as T
+#endif
 import qualified Data.Yaml                     as Yaml
 import           Hakyll.Core.Metadata
 import           Hakyll.Core.Provider.Metadata
@@ -26,10 +32,7 @@
 testPage01 :: Assertion
 testPage01 =
     (meta [("foo", "bar")], "qux\n") `expectRight` parsePage
-    "---\n\
-    \foo: bar\n\
-    \---\n\
-    \qux\n"
+    "---\nfoo: bar\n---\nqux\n"
 
 
 --------------------------------------------------------------------------------
@@ -37,21 +40,22 @@
 testPage02 =
     (meta [("description", descr)], "Hello I am dog\n") `expectRight`
     parsePage
-    "---\n\
-    \description: A long description that would look better if it\n\
-    \             spanned multiple lines and was indented\n\
-    \---\n\
-    \Hello I am dog\n"
+    "---\ndescription: A long description that would look better if it\n             spanned multiple lines and was indented\n---\nHello I am dog\n"
   where
     descr :: String
     descr =
-        "A long description that would look better if it \
-        \spanned multiple lines and was indented"
+        "A long description that would look better if it spanned multiple lines and was indented"
 
 
 --------------------------------------------------------------------------------
 meta :: Yaml.ToJSON a => [(String, a)] -> Metadata
-meta pairs = HMS.fromList [(T.pack k, Yaml.toJSON v) | (k, v) <- pairs]
+meta pairs = KeyMap.fromList [(keyFromString k, Yaml.toJSON v) | (k, v) <- pairs]
+  where
+#if MIN_VERSION_aeson(2,0,0)
+  keyFromString = AK.fromString
+#else
+  keyFromString = T.pack
+#endif
 
 
 --------------------------------------------------------------------------------
diff --git a/tests/Hakyll/Web/Html/RelativizeUrls/Tests.hs b/tests/Hakyll/Web/Html/RelativizeUrls/Tests.hs
--- a/tests/Hakyll/Web/Html/RelativizeUrls/Tests.hs
+++ b/tests/Hakyll/Web/Html/RelativizeUrls/Tests.hs
@@ -35,4 +35,6 @@
         , "<script src=\"//ajax.googleapis.com/jquery.min.js\"></script>" @=?
             relativizeUrlsWith "../.."
                 "<script src=\"//ajax.googleapis.com/jquery.min.js\"></script>"
+        , "<img srcset=\"./image.png 200w, ./image2.png 400w\" />"  @=?
+            relativizeUrlsWith "." "<img srcset=\"/image.png 200w, /image2.png 400w\" />"
         ]
diff --git a/tests/Hakyll/Web/Html/Tests.hs b/tests/Hakyll/Web/Html/Tests.hs
--- a/tests/Hakyll/Web/Html/Tests.hs
+++ b/tests/Hakyll/Web/Html/Tests.hs
@@ -8,6 +8,7 @@
 import           Data.Char        (toUpper)
 import           Test.Tasty       (TestTree, testGroup)
 import           Test.Tasty.HUnit ((@=?))
+import qualified Text.HTML.TagSoup               as TS
 
 
 --------------------------------------------------------------------------------
@@ -34,6 +35,23 @@
             demoteHeadersBy 0 "<h4>A h4 title</h4>" -- Assert that a demotion of @N < 1@ is a no-op.
         ]
 
+    , fromAssertions "getUrls"
+        [ ["/image1.png", "/image2.jpeg", "https://example.com", "/game.swf", "/poster.jpeg"] @=?
+            getUrls [
+                TS.TagOpen "img" [("src", "/image1.png")]
+              , TS.TagOpen "img" [("src", "/image2.jpeg")]
+              , TS.TagOpen "a" [("href", "https://example.com")]
+              , TS.TagOpen "object" [("data", "/game.swf")]
+              , TS.TagOpen "video" [("poster", "/poster.jpeg")]
+              ]
+        , ["/image1.png", "/image2.jpeg", "/image3.bmp"] @=?
+            getUrls [ TS.TagOpen "img" [("srcset", "/image1.png 10w, /image2.jpeg, /image3.bmp 1.3x")] ]
+
+        -- Invalid srcset specification means no URLs are extracted
+        , [] @=?
+            getUrls [ TS.TagOpen "img" [("srcset", "/image1.png 10wide, /image2.jpeg, /image3.bmp 1.3px")] ]
+        ]
+
     , fromAssertions "withUrls"
         [ "<a href=\"FOO\">bar</a>" @=?
             withUrls (map toUpper) "<a href=\"foo\">bar</a>"
@@ -51,6 +69,16 @@
         -- Test minimizing elements
         , "<meta bar=\"foo\" />" @=?
             withUrls id "<meta bar=\"foo\" />"
+
+        -- Test that URLs are extracted from img's srcset
+        , "<img srcset=\"foo 200w\" />" @=?
+            withUrls (const "foo") "<img srcset=\"/path/to/image.png 200w\" />"
+        , "<img srcset=\"bar 200w, bar 400w\" />" @=?
+            withUrls (const "bar") "<img srcset=\"/small.jpeg 200w, /img/large.jpeg 400w\" />"
+
+        -- Invalid srcsets are left unchanged
+        , "<img srcset=\"/image1.png 200px\" />" @=?
+            withUrls (const "bar") "<img srcset=\"/image1.png 200px\" />"
         ]
 
     , fromAssertions "toUrl"
diff --git a/tests/Hakyll/Web/Pandoc/Biblio/Tests.hs b/tests/Hakyll/Web/Pandoc/Biblio/Tests.hs
--- a/tests/Hakyll/Web/Pandoc/Biblio/Tests.hs
+++ b/tests/Hakyll/Web/Pandoc/Biblio/Tests.hs
@@ -25,6 +25,8 @@
 tests :: TestTree
 tests = testGroup "Hakyll.Web.Pandoc.Biblio.Tests" $
     [ goldenTest01
+    , goldenTest02
+    , goldenTest03
     ]
 
 --------------------------------------------------------------------------------
@@ -36,7 +38,7 @@
 goldenTest01 =
     goldenVsString
         "biblio01"
-        (goldenTestsDataDir </> "biblio01.golden")
+        (goldenTestsDataDir </> "cites-meijer.golden")
         (do
             -- Code lifted from https://github.com/jaspervdj/hakyll-citeproc-example.
             logger <- Logger.new Logger.Error
@@ -60,6 +62,74 @@
 
             output <- fmap LBS.fromStrict $ B.readFile $
                     destinationDirectory testConfiguration </> "page.html"
+
+            cleanTestEnv
+
+            return output)
+
+goldenTest02 :: TestTree
+goldenTest02 =
+    goldenVsString
+        "biblio02"
+        (goldenTestsDataDir </> "cites-meijer.golden")
+        (do
+            -- Code lifted from https://github.com/jaspervdj/hakyll-citeproc-example.
+            logger <- Logger.new Logger.Error
+            let config = testConfiguration { providerDirectory = goldenTestsDataDir }
+            _ <- run RunModeNormal config logger $ do
+                let myPandocBiblioCompiler = do
+                        csl <- load "chicago.csl"
+                        bib <- load "refs.yaml"
+                        getResourceBody >>=
+                            readPandocBiblio defaultHakyllReaderOptions csl bib >>=
+                            return . writePandoc
+
+                match "default.html" $ compile templateCompiler
+                match "chicago.csl" $ compile cslCompiler
+                match "refs.yaml"    $ compile biblioCompiler
+                match "page.markdown" $ do
+                    route $ setExtension "html"
+                    compile $
+                        myPandocBiblioCompiler >>=
+                        loadAndApplyTemplate "default.html" defaultContext
+
+            output <- fmap LBS.fromStrict $ B.readFile $
+                    destinationDirectory testConfiguration </> "page.html"
+
+            cleanTestEnv
+
+            return output)
+
+goldenTest03 :: TestTree
+goldenTest03 =
+    goldenVsString
+        "biblio03"
+        (goldenTestsDataDir </> "cites-multiple.golden")
+        (do
+            -- Code lifted from https://github.com/jaspervdj/hakyll-citeproc-example.
+            logger <- Logger.new Logger.Error
+            let config = testConfiguration { providerDirectory = goldenTestsDataDir }
+            _ <- run RunModeNormal config logger $ do
+                let myPandocBiblioCompiler = do
+                        csl <- load "chicago.csl"
+                        bib1 <- load "refs.bib"
+                        bib2 <- load "refs2.yaml"
+                        getResourceBody >>=
+                            readPandocBiblios defaultHakyllReaderOptions csl [bib1, bib2] >>=
+                            return . writePandoc
+
+                match "default.html" $ compile templateCompiler
+                match "chicago.csl" $ compile cslCompiler
+                match "refs.bib"    $ compile biblioCompiler
+                match "refs2.yaml"    $ compile biblioCompiler
+                match "cites-multiple.markdown" $ do
+                    route $ setExtension "html"
+                    compile $
+                        myPandocBiblioCompiler >>=
+                        loadAndApplyTemplate "default.html" defaultContext
+
+            output <- fmap LBS.fromStrict $ B.readFile $
+                    destinationDirectory testConfiguration </> "cites-multiple.html"
 
             cleanTestEnv
 
diff --git a/tests/data/biblio/biblio01.golden b/tests/data/biblio/biblio01.golden
deleted file mode 100644
--- a/tests/data/biblio/biblio01.golden
+++ /dev/null
@@ -1,16 +0,0 @@
-<!doctype html>
-<html lang="en">
-    <head>
-        <meta charset="utf-8">
-        <title>This page cites a paper.</title>
-    </head>
-    <body>
-        <h1>This page cites a paper.</h1>
-        <p>I would like to cite one of my favourite papers <span class="citation" data-cites="meijer1991functional">(Meijer, Fokkinga, and Paterson 1991)</span> here.</p>
-<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
-<div id="ref-meijer1991functional" class="csl-entry" role="doc-biblioentry">
-Meijer, Erik, Maarten Fokkinga, and Ross Paterson. 1991. <span>“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire.”</span> In <em>Conference on Functional Programming Languages and Computer Architecture</em>, 124–44. Springer.
-</div>
-</div>
-    </body>
-</html>
diff --git a/tests/data/biblio/cites-meijer.golden b/tests/data/biblio/cites-meijer.golden
new file mode 100644
--- /dev/null
+++ b/tests/data/biblio/cites-meijer.golden
@@ -0,0 +1,16 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <title>This page cites a paper.</title>
+    </head>
+    <body>
+        <h1>This page cites a paper.</h1>
+        <p>I would like to cite one of my favourite papers <span class="citation" data-cites="meijer1991functional">(Meijer, Fokkinga, and Paterson 1991)</span> here.</p>
+<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
+<div id="ref-meijer1991functional" class="csl-entry" role="doc-biblioentry">
+Meijer, Erik, Maarten Fokkinga, and Ross Paterson. 1991. <span>“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire.”</span> In <em>Conference on Functional Programming Languages and Computer Architecture</em>, 124–44. Springer.
+</div>
+</div>
+    </body>
+</html>
diff --git a/tests/data/biblio/cites-multiple.golden b/tests/data/biblio/cites-multiple.golden
new file mode 100644
--- /dev/null
+++ b/tests/data/biblio/cites-multiple.golden
@@ -0,0 +1,20 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <title>This page cites a paper and a book.</title>
+    </head>
+    <body>
+        <h1>This page cites a paper and a book.</h1>
+        <p>I would like to cite one of my favourite papers <span class="citation" data-cites="meijer1991functional">(Meijer, Fokkinga, and Paterson 1991)</span> here.</p>
+<p>And also a book <span class="citation" data-cites="lipovaca2012">(Lipovača 2012)</span>.</p>
+<div id="refs" class="references csl-bib-body hanging-indent" role="doc-bibliography">
+<div id="ref-lipovaca2012" class="csl-entry" role="doc-biblioentry">
+Lipovača, Miran. 2012. <em>Learn You a Haskell for Great Good! A Beginner’s Guide</em>. San Francisco, CA: No Starch Press.
+</div>
+<div id="ref-meijer1991functional" class="csl-entry" role="doc-biblioentry">
+Meijer, Erik, Maarten Fokkinga, and Ross Paterson. 1991. <span>“Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire.”</span> In <em>Conference on Functional Programming Languages and Computer Architecture</em>, 124–44. Springer.
+</div>
+</div>
+    </body>
+</html>
diff --git a/tests/data/biblio/cites-multiple.markdown b/tests/data/biblio/cites-multiple.markdown
new file mode 100644
--- /dev/null
+++ b/tests/data/biblio/cites-multiple.markdown
@@ -0,0 +1,7 @@
+---
+title: This page cites a paper and a book.
+---
+
+I would like to cite one of my favourite papers [@meijer1991functional] here.
+
+And also a book [@lipovaca2012].
diff --git a/tests/data/biblio/refs.yaml b/tests/data/biblio/refs.yaml
new file mode 100644
--- /dev/null
+++ b/tests/data/biblio/refs.yaml
@@ -0,0 +1,18 @@
+---
+references:
+- id: meijer1991functional
+  author:
+    - family: Meijer
+      given: Erik
+    - family: Fokkinga
+      given: Maarten
+    - family: Paterson
+      given: Ross
+  container-title: Conference on functional programming languages and computer architecture
+  issued:
+    - year: 1991
+  page: 124–144
+  publisher: Springer
+  title: Functional programming with bananas, lenses, envelopes and barbed wire
+  type: paper-conference
+...
diff --git a/tests/data/biblio/refs2.yaml b/tests/data/biblio/refs2.yaml
new file mode 100644
--- /dev/null
+++ b/tests/data/biblio/refs2.yaml
@@ -0,0 +1,18 @@
+---
+references:
+- id: lipovaca2012
+  author:
+    - family: Lipovača
+      given: Miran
+  call-number: QA76.73.H37 L69 2012
+  event-place: San Francisco, CA
+  ISBN: 978-1-59327-283-8
+  issued:
+    - year: 2012
+  number-of-pages: '375'
+  publisher: No Starch Press
+  publisher-place: San Francisco, CA
+  source: Library of Congress ISBN
+  title: Learn you a Haskell for great good! a beginner's guide
+  type: book
+...
