diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,16 @@
 
 [KaC]: <https://keepachangelog.com/en/1.0.0/>
 
+## 0.3.0.0 (2023-05-28)
+
+## Breaking
+
+* Add support for `optparse-applicative` `0.18`
+
+### Non-Breaking
+
+* Bump `ansi-wl-pprint` dependency version upper bound
+
 ## 0.2.1.0 (2023-03-21)
 
 ### Breaking
diff --git a/app/LibOA.hs b/app/LibOA.hs
--- a/app/LibOA.hs
+++ b/app/LibOA.hs
@@ -9,15 +9,21 @@
 -- @optparse-applicative@.  I do not feel that it is worth maintaining yet
 -- another helper package on Hackage, so I just copy the code to different
 -- projects as required.  If the library grows to a substantial size or others
--- with to use it, I will reconsider.
+-- want to use it, I will reconsider.
 --
--- Revision: 2022-01-02
+-- Revision: 2023-05-26
 ------------------------------------------------------------------------------
 
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE LambdaCase #-}
 {-# LANGUAGE TupleSections #-}
 
+#if defined(MIN_VERSION_ansi_wl_pprint)
+#if MIN_VERSION_ansi_wl_pprint (1,0,2)
+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
+#endif
+#endif
+
 module LibOA
   ( -- * Options
     -- $Options
@@ -28,14 +34,23 @@
     -- * Help
   , (<||>)
   , section
+  , section'
   , table
   , table_
   , vspace
+    -- ** Compatibility
+  , Doc
+  , (<$$>)
+  , empty
+  , string
+  , vcat
   ) where
 
 -- https://hackage.haskell.org/package/ansi-wl-pprint
+#if !MIN_VERSION_optparse_applicative (0,18,0)
 import qualified Text.PrettyPrint.ANSI.Leijen as Doc
 import Text.PrettyPrint.ANSI.Leijen (Doc)
+#endif
 
 -- https://hackage.haskell.org/package/base
 import Data.List (intersperse, transpose)
@@ -50,8 +65,16 @@
 import qualified Options.Applicative.Builder.Internal as OABI
 #endif
 import qualified Options.Applicative.Common as OAC
+#if MIN_VERSION_optparse_applicative (0,18,0)
+import Options.Applicative.Help.Pretty (Doc)
+#endif
 import qualified Options.Applicative.Types as OAT
 
+-- https://hackage.haskell.org/package/prettyprinter
+#if MIN_VERSION_optparse_applicative (0,18,0)
+import qualified Prettyprinter as Doc
+#endif
+
 ------------------------------------------------------------------------------
 -- $Options
 --
@@ -103,8 +126,12 @@
 commands :: OA.Parser a -> [String]
 commands =
     let go _ opt = case OAT.optMain opt of
+#if MIN_VERSION_optparse_applicative (0,18,0)
+           OAT.CmdReader _ cmdPs -> reverse $ fst <$> cmdPs
+#else
            OAT.CmdReader _ cmds _ -> reverse cmds
-           _otherReader           -> []
+#endif
+           _otherReader -> []
     in  concat . OAC.mapParser go
 
 ------------------------------------------------------------------------------
@@ -115,22 +142,26 @@
 d1 <||> d2 = d1 <> Doc.line <> Doc.line <> d2
 infixr 5 <||>
 
--- | Create a section with a title and indented body
+-- | Create a section with a title and body indented by 2 spaces
 section :: String -> Doc -> Doc
-section title = (Doc.text title Doc.<$$>) . Doc.indent 2
+section = section' 2
 
+-- | Create a section with a title and body indented by specified spaces
+section' :: Int -> String -> Doc -> Doc
+section' numSpaces title = (string title <$$>) . Doc.indent numSpaces
+
 -- | Create a table, with formatting
 table :: Int -> [[(String, Doc -> Doc)]] -> Doc
 table sep rows = Doc.vcat $
-    map (fromMaybe Doc.empty . foldr go Nothing . zip lengths) rows
+    map (fromMaybe empty . foldr go Nothing . zip lengths) rows
   where
     lengths :: [Int]
     lengths = map ((+) sep . maximum . map (length . fst)) $ transpose rows
 
     go :: (Int, (String, Doc -> Doc)) -> Maybe Doc -> Maybe Doc
     go (len, (s, f)) = Just . \case
-      Just doc -> Doc.fill len (f $ Doc.string s) <> doc
-      Nothing  -> f $ Doc.string s
+      Just doc -> Doc.fill len (f $ string s) <> doc
+      Nothing  -> f $ string s
 
 -- | Create a table, without formatting
 table_ :: Int -> [[String]] -> Doc
@@ -139,3 +170,30 @@
 -- | Vertically space documents with blank lines between them
 vspace :: [Doc] -> Doc
 vspace = mconcat . intersperse (Doc.line <> Doc.line)
+
+------------------------------------------------------------------------------
+-- $Compatibility
+
+(<$$>) :: Doc -> Doc -> Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+l <$$> r = l <> Doc.line <> r
+#else
+(<$$>) = (Doc.<$$>)
+#endif
+
+empty :: Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+empty = Doc.emptyDoc
+#else
+empty = Doc.empty
+#endif
+
+string :: String -> Doc
+#if MIN_VERSION_optparse_applicative (0,18,0)
+string = Doc.pretty
+#else
+string = Doc.string
+#endif
+
+vcat :: [Doc] -> Doc
+vcat = Doc.vcat
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -6,12 +6,16 @@
 -- License     : MIT
 ------------------------------------------------------------------------------
 
+{-# LANGUAGE CPP #-}
 {-# LANGUAGE RecordWildCards #-}
 
-module Main (main) where
+#if defined(MIN_VERSION_ansi_wl_pprint)
+#if MIN_VERSION_ansi_wl_pprint (1,0,2)
+{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
+#endif
+#endif
 
--- https://hackage.haskell.org/package/ansi-wl-pprint
-import Text.PrettyPrint.ANSI.Leijen (Doc)
+module Main (main) where
 
 -- https://hackage.haskell.org/package/base
 import Control.Applicative (optional)
@@ -191,19 +195,19 @@
               ]
           ]
 
-    sourceFormatHelp :: Doc
+    sourceFormatHelp :: LibOA.Doc
     sourceFormatHelp = LibOA.section "SOURCE options:" $ LibOA.table_ 2
       [ [TTC.render format, SourceFormat.describe format]
       | format <- SourceFormat.list
       ]
 
-    targetFormatHelp :: Doc
+    targetFormatHelp :: LibOA.Doc
     targetFormatHelp = LibOA.section "TARGET options:" $ LibOA.table_ 2
       [ [TTC.render format, TargetFormat.describe format]
       | format <- TargetFormat.list
       ]
 
-    defaultsHelp :: Doc
+    defaultsHelp :: LibOA.Doc
     defaultsHelp = LibOA.section "Default options:" $ LibOA.table_ 2
       [ [ext, TTC.render lang ++ " (" ++ TTC.render format ++ ")"]
       | (ext, (format, lang)) <- SourceDefaults.extensionDefaults
diff --git a/literatex.cabal b/literatex.cabal
--- a/literatex.cabal
+++ b/literatex.cabal
@@ -1,5 +1,5 @@
 name:           literatex
-version:        0.2.1.0
+version:        0.3.0.0
 category:       Utils
 synopsis:       transform literate source code to Markdown
 description:
@@ -24,9 +24,9 @@
    || ==8.8.4
    || ==8.10.7
    || ==9.0.2
-   || ==9.2.7
-   || ==9.4.4
-   || ==9.6.1
+   || ==9.2.8
+   || ==9.4.5
+   || ==9.6.2
 
 extra-source-files:
   CHANGELOG.md
@@ -40,9 +40,11 @@
   description: build examples
   default: False
 
-flag write-hie
-  description: write .hie files
+-- This flag is referenced in the Stack build-constraints.yaml configuration.
+flag optparse-applicative_ge_0_18
+  description: Use optparse-applicative 0.18 or newer
   default: False
+  manual: False
 
 library
   hs-source-dirs: src
@@ -68,10 +70,7 @@
   default-language: Haskell2010
   default-extensions:
       OverloadedStrings
-  if flag(write-hie)
-    ghc-options: -Wall -fwrite-ide-info -hiedir=.hie
-  else
-    ghc-options: -Wall
+  ghc-options: -Wall
 
 executable literatex
   hs-source-dirs: app
@@ -79,11 +78,17 @@
   other-modules:
       LibOA
   build-depends:
-      ansi-wl-pprint >=0.6.8 && <0.7
-    , base
-    , optparse-applicative >=0.13 && <0.18
+      base
     , literatex
     , ttc
+  if flag(optparse-applicative_ge_0_18)
+    build-depends:
+        optparse-applicative >=0.18 && <0.19
+      , prettyprinter >=1.7.1 && <1.8
+  else
+    build-depends:
+        ansi-wl-pprint >=0.6.8 && <1.1
+      , optparse-applicative >=0.13 && <0.18
   default-language: Haskell2010
   ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
 
