diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,8 @@
+### 0.4.0.0
+
+- Dropped support for GHC older than *8.0* and *Pandoc* older than *2.8*.
+- Allow Pandoc extensions available for the output format.
+
 ### 0.3.0.0
 
 - Compatibility with Pandoc *3.0*.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
 The following license covers this documentation, and the source code, except
 where otherwise indicated.
 
-Copyright 2016-2023, Alexey Radkov. All rights reserved.
+Copyright 2016-2024, Alexey Radkov. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -107,6 +107,19 @@
 actual paragraph contents will be inserted inside them. Notice that wrapping
 inside code blocks is not allowed in `para_style` block.
 
+Build and install the filter with commands
+
+```ShellSession
+$ cabal build
+$ cabal install
+```
+
+The program is also available at *Hackage*, so you can install it with
+
+```ShellSession
+$ cabal install pandoc-stylefrommeta
+```
+
 <br><hr><a name="fn1"><sup>**1**</sup></a>&nbsp; All YAML and markdown code
 examples in this document have 4-space indentation as the document requires this
 for correct rendering. As such, when they are copied and pasted for playing
diff --git a/pandoc-stylefrommeta.cabal b/pandoc-stylefrommeta.cabal
--- a/pandoc-stylefrommeta.cabal
+++ b/pandoc-stylefrommeta.cabal
@@ -1,5 +1,5 @@
 name:                    pandoc-stylefrommeta
-version:                 0.3.0.0
+version:                 0.4.0.0
 synopsis:                Pandoc filter to customize links, images and paragraphs
 description:             Pandoc filter to customize links, images and paragraphs
         (with restrictions). Styles are read from the metadata of the document:
@@ -7,45 +7,29 @@
 homepage:                http://github.com/lyokha/styleFromMeta
 license:                 BSD3
 license-file:            LICENSE
-extra-source-files:      Changelog.md README.md
+extra-doc-files:         Changelog.md README.md
 author:                  Alexey Radkov <alexey.radkov@gmail.com>
 maintainer:              Alexey Radkov <alexey.radkov@gmail.com>
 stability:               stable
-copyright:               2016-2023 Alexey Radkov
+copyright:               2016-2024 Alexey Radkov
 category:                Text
 build-type:              Simple
 cabal-version:           1.20
 
 source-repository head
   type:                  git
-  location:              git@github.com:lyokha/styleFromMeta.git
-
-flag Pandoc2
-  description:           Use Pandoc 2.0 and newer
-                         (requires text and bytestring)
-
-flag PandocUseText
-  description:           Use Pandoc migrated from String to Text
-                         (requires pandoc >= 2.8 and pandoc-types >= 1.20)
+  location:              https://github.com/lyokha/styleFromMeta.git
 
 executable styleFromMeta
   default-language:      Haskell2010
-  build-depends:         base >= 4.8 && < 5
-                       , pandoc >= 1.12
-                       , pandoc-types >= 1.12
+  build-depends:         base >= 4.9 && < 5
+                       , pandoc >= 2.8
+                       , pandoc-types >= 1.20
                        , containers >= 0.2
-
-  if flag(Pandoc2)
-    build-depends:       pandoc >= 2.0
-                       , pandoc-types >= 1.17.2
-                       , text
                        , bytestring
+                       , text
 
-  if flag(PandocUseText)
-    build-depends:       pandoc >= 2.8
-                       , pandoc-types >= 1.20
-  else
-    build-depends:       extra
+  ghc-options:          -Wall
 
   main-is:               styleFromMeta.hs
 
diff --git a/styleFromMeta.hs b/styleFromMeta.hs
--- a/styleFromMeta.hs
+++ b/styleFromMeta.hs
@@ -1,106 +1,48 @@
-{-# LANGUAGE CPP, ViewPatterns, PatternGuards, PatternSynonyms #-}
-
-#if MIN_VERSION_pandoc_types(1,20,0)
+{-# LANGUAGE CPP, ViewPatterns, PatternSynonyms, LambdaCase #-}
 {-# LANGUAGE OverloadedStrings #-}
-#endif
 
 import           Text.Pandoc.JSON
 import           Text.Pandoc.Walk (walk)
-import           Text.Pandoc.Options (def)
+import           Text.Pandoc.Options (WriterOptions (writerExtensions), def)
 import           Text.Pandoc.Shared (stringify)
-import qualified Data.Map as M
-#if !MIN_VERSION_pandoc_types(1,20,0)
-import           Data.List.Extra (replace)
-#endif
-
-#if MIN_VERSION_pandoc(2,0,0)
 import           Text.Pandoc.Writers (Writer (..), getWriter)
 import           Text.Pandoc.Class (runPure)
-import qualified Data.ByteString.Lazy.Char8 as C8L
-import qualified Data.Text as T
-import           Control.Exception (displayException)
-#else
-import           Text.Pandoc (Writer (..), getWriter)
-#endif
-
-#if MIN_VERSION_pandoc(2,8,0)
-import           Text.Pandoc.Class (PandocPure)
-import           Text.Pandoc.Error (PandocError)
-#endif
-
+import           Text.Pandoc.Error (renderError)
 #if MIN_VERSION_pandoc(3,0,0)
 import           Text.Pandoc.Format (FlavoredFormat (..))
 #endif
-
-#if MIN_VERSION_pandoc_types(1,20,0)
-type STRING = T.Text
-rEPLACE :: STRING -> STRING -> STRING -> STRING
-rEPLACE = T.replace
-tOSTRING :: T.Text -> String
-tOSTRING = T.unpack
-fROMSTRING :: String -> T.Text
-fROMSTRING = T.pack
-tOTEXT :: T.Text -> T.Text
-tOTEXT = id
-#else
-type STRING = String
-rEPLACE :: STRING -> STRING -> STRING -> STRING
-rEPLACE = replace
-tOSTRING :: String -> String
-tOSTRING = id
-fROMSTRING :: String -> String
-fROMSTRING = id
-tOTEXT :: T.Text -> String
-tOTEXT = T.unpack
-#endif
-
-#if MIN_VERSION_pandoc(2,8,0)
-rUNGETWRITER :: PandocPure a -> Either PandocError a
-rUNGETWRITER = runPure
-#else
-rUNGETWRITER :: a -> a
-rUNGETWRITER = id
-#endif
-
-#if MIN_VERSION_pandoc(3,0,0)
-tOWRITERFORMAT :: Format -> FlavoredFormat
-tOWRITERFORMAT (Format "tex") = FlavoredFormat "latex" mempty
-tOWRITERFORMAT (Format fmt)   = FlavoredFormat fmt mempty
-tOFORMATNAME :: FlavoredFormat -> STRING
-tOFORMATNAME = formatName
-#else
-tOWRITERFORMAT :: Format -> STRING
-tOWRITERFORMAT (Format "tex") = "latex"
-tOWRITERFORMAT (Format fmt)   = fmt
-tOFORMATNAME :: STRING -> STRING
-tOFORMATNAME = id
-#endif
+import           Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.ByteString.Lazy.Char8 as C8L
+import qualified Data.Map as M
 
-#if MIN_TOOL_VERSION_ghc(7,10,1)
-pattern Style :: STRING -> Inline
-#endif
+pattern Style :: Text -> Inline
 pattern Style x <- Math InlineMath x
 
-#if MIN_TOOL_VERSION_ghc(7,10,1)
-pattern Subst :: STRING -> Inline
-#endif
+pattern Subst :: Text -> Inline
 pattern Subst x = Math InlineMath x
 
-#if MIN_TOOL_VERSION_ghc(7,10,1)
-pattern SubstVerbatim :: STRING -> Inline
-#endif
+pattern SubstVerbatim :: Text -> Inline
 pattern SubstVerbatim x <- Math DisplayMath x
 
-#if MIN_TOOL_VERSION_ghc(7,10,1)
 pattern Alt :: [Inline] -> [Inline]
-#endif
 pattern Alt x <- (dropWhile (== Space) -> x)
 
-type MMap = M.Map STRING MetaValue
+type MMap = M.Map Text MetaValue
 type PureInlineParams = ([Inline], Target)          -- style:(alt, target)
 type InlineParams = (Inline, [Inline], Target)      -- (style:alt, target)
 type InlineCons = [Inline] -> Target -> Inline      -- Image or Link
 
+#if MIN_VERSION_pandoc(3,0,0)
+toWriterFormat :: Format -> FlavoredFormat
+toWriterFormat (Format "tex") = FlavoredFormat "latex" mempty
+toWriterFormat (Format fmt)   = FlavoredFormat fmt mempty
+#else
+toWriterFormat :: Format -> Text
+toWriterFormat (Format "tex") = "latex"
+toWriterFormat (Format fmt)   = fmt
+#endif
+
 styleFromMeta :: Maybe Format -> Pandoc -> IO Pandoc
 styleFromMeta (Just fm) (Pandoc m bs) = do
     let b = unMeta m
@@ -133,18 +75,17 @@
                 RawInline fm $ substParamsInRawBlock fm params vb
             substInlineStyle' (Just (MetaBlocks mbs)) =
                 RawInline fm $ renderInlines fm $ map substInlineStyle'' mbs
-                    where substInlineStyle'' mb =
-                            case mb of
-                                Plain is       -> substPlainParams is
-                                Para is        -> substPlainParams is
-                                d@Div {}       ->
-                                    RawInline fm $
-                                        substParamsInRawBlock fm params $
-                                            renderBlocks fm [d]
-                                RawBlock bfm b ->
-                                    RawInline bfm $
-                                        substParamsInRawBlock bfm params b
-                                _              -> i
+                where substInlineStyle'' = \case
+                          Plain is       -> substPlainParams is
+                          Para is        -> substPlainParams is
+                          d@Div {}       ->
+                              RawInline fm $
+                                  substParamsInRawBlock fm params $
+                                      renderBlocks fm [d]
+                          RawBlock bfm b ->
+                              RawInline bfm $
+                                  substParamsInRawBlock bfm params b
+                          _              -> i
             substInlineStyle' Nothing = cons alt tgt
             substInlineStyle' _ = i
         in substInlineStyle' $ M.lookup fmt mm
@@ -169,9 +110,9 @@
     substParamsInRawBlock fm params s
 substParams _  _               i                       = i
 
-substParamsInRawBlock :: Format -> PureInlineParams -> STRING -> STRING
+substParamsInRawBlock :: Format -> PureInlineParams -> Text -> Text
 substParamsInRawBlock fm (alt, (src, title)) s =
-    foldr (\(p, is) -> rEPLACE p $ renderInlines fm is) s
+    foldr (\(p, is) -> T.replace p $ renderInlines fm is) s
           [("$ALT$",     alt                                           )
           ,("$SRC$",     [Str src]                                     )
           ,("$TITLE$",   [Str title]                                   )
@@ -180,29 +121,22 @@
           ,("$$TITLE$$", [RawInline fm title]                          )
           ]
 
-renderBlocks :: Format -> [Block] -> STRING
+renderBlocks :: Format -> [Block] -> Text
 renderBlocks fm p =
-    let fmt = tOWRITERFORMAT fm
-        writer = getWriter fmt
+    let writer = getWriter $ toWriterFormat fm
         doc = Pandoc (Meta M.empty) p
-    in case rUNGETWRITER writer of
-        Left _ -> error $ "Unknown format " ++ tOSTRING (tOFORMATNAME fmt)
-#if MIN_VERSION_pandoc(2,0,0)
-        Right (TextWriter w, _) ->
-            case runPure $ w def doc of
-                Left e -> fROMSTRING $ displayException e
-                Right r -> tOTEXT r
-        Right (ByteStringWriter w, _) ->
-            case runPure $ w def doc of
-                Left e -> fROMSTRING $ displayException e
-                Right r -> fROMSTRING $ C8L.unpack r
-#else
-        Right (PureStringWriter w) -> w def doc
-        _ -> error $ "Unsupported format " ++ tOSTRING fmt ++
-            ", use Pandoc 2.0 or newer!"
-#endif
+    in case runPure writer of
+           Left e -> renderError e
+           Right (TextWriter w, ext) ->
+               case runPure $ w def {writerExtensions = ext} doc of
+                   Left e -> renderError e
+                   Right r -> r
+           Right (ByteStringWriter w, ext) ->
+               case runPure $ w def {writerExtensions = ext} doc of
+                   Left e -> renderError e
+                   Right r -> T.pack $ C8L.unpack r
 
-renderInlines :: Format -> [Inline] -> STRING
+renderInlines :: Format -> [Inline] -> Text
 renderInlines fm p = renderBlocks fm [Plain p]
 
 main :: IO ()
