diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,19 +1,18 @@
-[![Hackage](https://img.shields.io/hackage/v/pcre-heavy.svg?style=flat)](https://hackage.haskell.org/package/pcre-heavy)
+[![Hackage](https://img.shields.io/hackage/v/pcre-heavy.svg?style=flat) ![](https://img.shields.io/endpoint?url=https://hackage-downloads-badge.deno.dev/pcre-heavy)](https://hackage.haskell.org/package/pcre-heavy)
 [![unlicense](https://img.shields.io/badge/un-license-green.svg?style=flat)](https://unlicense.org)
+[![Support me on Patreon](https://img.shields.io/badge/dynamic/json?logo=patreon&color=%23e85b46&label=support%20me%20on%20patreon&query=data.attributes.patron_count&suffix=%20patrons&url=https%3A%2F%2Fwww.patreon.com%2Fapi%2Fcampaigns%2F9395291)](https://www.patreon.com/valpackett)
 
 # pcre-heavy
 
-*Finally!* A Haskell regular expressions library that does not suck.
+A Haskell regular expressions library with support for multiple matches and replacements:
 
 - based on [pcre-light], none of that regex-base complicated pluggable-backend stuff
-- takes and returns [ConvertibleStrings] everywhere, use ANY STRING TYPE (String, ByteString, Lazy ByteString, Text, Lazy Text) -- but you need a bit more type annotations (or [ClassyPrelude]'s `asText`, `asString`, etc.) if you use `OverloadedStrings` which you probably can't live without
-- a QuasiQuoter for regexps that does compile time checking (BTW, [vim2hs] has correct syntax highlighting for that!)
-- **SEARCHES FOR MULTIPLE MATCHES! DOES REPLACEMENT!**
+- takes and returns [ConvertibleStrings] everywhere, use any common string type (String, ByteString, Lazy ByteString, Text, Lazy Text) -- but you need a bit more type annotations (or [ClassyPrelude]'s `asText`, `asString`, etc.) if you use `OverloadedStrings` which you probably can't live without
+- provides a QuasiQuoter for regexps that does compile time checking
 
 [pcre-light]: https://hackage.haskell.org/package/pcre-light
 [ConvertibleStrings]: https://hackage.haskell.org/package/string-conversions
 [ClassyPrelude]: https://hackage.haskell.org/package/classy-prelude
-[vim2hs]: https://github.com/dag/vim2hs#quasi-quoting
 
 ## Usage
 
@@ -65,23 +64,25 @@
 `sub` replaces the first match, `gsub` replaces all matches.
 
 ```haskell
--- You can use a Stringable type as the replacement...
+-- You can use a convertible string type `a` as the replacement...
 >>> gsub [re|\d+|] "!!!NUMBER!!!" "Copyright (c) 2015 The 000 Group"
 "Copyright (c) !!!NUMBER!!! The !!!NUMBER!!! Group"
 
--- or a (Stringable a => [a] -> a) function -- that will get the groups...
+-- or a ([a] -> a) function -- that will get the groups...
 >>> gsub [re|%(\d+)(\w+)|] (\(d:w:_) -> "{" ++ d ++ " of " ++ w ++ "}" :: String) "Hello, %20thing"
 "Hello, {20 of thing}"
 
--- or a (Stringable a => a -> a) function -- that will get the full match...
+-- or a (a -> a) function -- that will get the full match...
 >>> gsub [re|-\w+|] (\x -> "+" ++ (reverse $ drop 1 x) :: String) "hello -world"
 "hello +dlrow"
 
--- or a (Stringable a => a -> [a] -> a) function.
+-- or a (a -> [a] -> a) function.
 -- That will get both the full match and the groups.
 -- I have no idea why you would want to use that, but that's there :-)
 ```
 
+Note that functions are the _only_ way to use captured groups in the replacement. There is no "in string" syntax like in Perl or in Python.
+
 ### Splitting
 
 `split`, well, splits.
@@ -117,12 +118,6 @@
 ```
 
 [stack]: https://github.com/commercialhaskell/stack
-
-## Contributing
-
-Please feel free to submit pull requests!
-
-By participating in this project you agree to follow the [Contributor Code of Conduct](http://contributor-covenant.org/version/1/4/).
 
 ## License
 
diff --git a/library/Text/Regex/PCRE/Heavy.hs b/library/Text/Regex/PCRE/Heavy.hs
--- a/library/Text/Regex/PCRE/Heavy.hs
+++ b/library/Text/Regex/PCRE/Heavy.hs
@@ -55,7 +55,7 @@
 import           System.IO.Unsafe (unsafePerformIO)
 import           Foreign (withForeignPtr, allocaBytes, nullPtr, plusPtr, peekElemOff)
 
--- $
+-- $setup
 -- >>> :set -XQuasiQuotes -XFlexibleContexts -XOverloadedStrings
 -- >>> :m + Text.Regex.PCRE.Heavy
 -- >>> import qualified Text.Regex.PCRE.Light as PCRE
@@ -120,8 +120,8 @@
 -- It is lazy! If you only need the first match, just apply 'head' (or
 -- 'headMay' from the "safe" library) -- no extra work will be performed!
 --
--- >>> head $ scan [re|\s*entry (\d+) (\w+)\s*&?|] (" entry 1 hello  &entry 2 hi" :: String)
--- (" entry 1 hello  &",["1","hello"])
+-- >>> take 1 $ scan [re|\s*entry (\d+) (\w+)\s*&?|] (" entry 1 hello  &entry 2 hi" :: String)
+-- [(" entry 1 hello  &",["1","hello"])]
 scan ∷ (ConvertibleStrings SBS a, ConvertibleStrings a SBS) ⇒ Regex → a → [(a, [a])]
 scan r s = scanO r [] s
 
diff --git a/pcre-heavy.cabal b/pcre-heavy.cabal
--- a/pcre-heavy.cabal
+++ b/pcre-heavy.cabal
@@ -1,21 +1,20 @@
 name:            pcre-heavy
-version:         1.0.0.3
+version:         1.0.0.4
 synopsis:        A regexp (regex) library on top of pcre-light you can actually use.
 description:
-    A regular expressions library that does not suck.
+    A PCRE-based regular expressions library with support for multiple matches and replacements.
 
     Based on <https://hackage.haskell.org/package/pcre-light pcre-light>.
 
-    Takes and returns <https://hackage.haskell.org/package/stringable Stringables> everywhere.
+    Takes and returns <https://hackage.haskell.org/package/string-conversions convertible strings> everywhere.
 
     Includes a QuasiQuoter for regexps that does compile time checking.
 
-    SEARCHES FOR MULTIPLE MATCHES! DOES REPLACEMENT!
 category:        Web
 homepage:        https://codeberg.org/valpackett/pcre-heavy
 bug-reports:     https://codeberg.org/valpackett/pcre-heavy/issues
 author:          Val Packett
-copyright:       2015-2022 Val Packett <val@packett.cool>
+copyright:       2015-2025 Val Packett <val@packett.cool>
 maintainer:      val@packett.cool
 license:         PublicDomain
 license-file:    UNLICENSE
@@ -24,7 +23,7 @@
 extra-source-files:
     README.md
 tested-with:
-    GHC == 8.0.1
+    GHC == 9.10.1
 
 source-repository head
     type: git
@@ -37,21 +36,11 @@
       , pcre-light
       , bytestring
       , string-conversions
-      , semigroups
       , template-haskell >= 2.16.0.0
+    if impl(ghc < 8.0)
+        build-depends: semigroups
     default-language: Haskell2010
     exposed-modules:
         Text.Regex.PCRE.Heavy
     ghc-options: -Wall
     hs-source-dirs: library
-
-test-suite examples
-    build-depends:
-        base >= 4.3.0.0 && < 5
-      , Glob
-      , doctest
-    default-language: Haskell2010
-    ghc-options: -threaded
-    hs-source-dirs: test-suite
-    main-is: DocTest.hs
-    type: exitcode-stdio-1.0
diff --git a/test-suite/DocTest.hs b/test-suite/DocTest.hs
deleted file mode 100644
--- a/test-suite/DocTest.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-module Main (main) where
-
-import           System.FilePath.Glob (glob)
-import           Test.DocTest         (doctest)
-
-main :: IO ()
-main = glob "library/**/*.hs" >>= doctest
