    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    #ifdef EMBED_DATA_FILES
    {-# LANGUAGE TemplateHaskell #-}
    #endif
    {- |
    Module      : Text.Pandoc.Data
    Copyright   : Copyright (C) 2013-2024 John MacFarlane
    License     : GNU GPL, version 2 or above

    Maintainer  : John MacFarlane <jgm@berkeley@edu>
    Stability   : alpha
    Portability : portable

    Access to pandoc's data files.
    -}
    module Text.Pandoc.Data ( readDefaultDataFile
                            , readDataFile
                            , getDataFileNames
                            , defaultUserDataDir
                            ) where
    import Text.Pandoc.Class (PandocMonad(..), checkUserDataDir, getTimestamp,
                              getUserDataDir, getPOSIXTime)
    import Data.Time.Clock.POSIX (utcTimeToPOSIXSeconds)
    import qualified Data.ByteString.Lazy as BL
    import qualified Data.ByteString as B
    import Codec.Archive.Zip
    import qualified Data.Text as T
    import Control.Monad.Except (throwError)
    import Text.Pandoc.Error (PandocError(..))
    import System.FilePath
    import System.Directory
    import qualified Control.Exception as E
    #ifdef EMBED_DATA_FILES
    import Text.Pandoc.Data.BakedIn (dataFiles)
    import Text.Pandoc.Shared (makeCanonical)
    #else
    import Paths_pandoc (getDataDir)
    #endif

    -- | Read file from the default data files.
    readDefaultDataFile :: PandocMonad m => FilePath -> m B.ByteString
    readDefaultDataFile :: forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
    readDefaultDataFile FilePath
    "reference.docx" =
      [ByteString] -> ByteString
    B.concat ([ByteString] -> ByteString)
    -> (Archive -> [ByteString]) -> Archive -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [ByteString]
    BL.toChunks (LazyByteString -> [ByteString])
    -> (Archive -> LazyByteString) -> Archive -> [ByteString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Archive -> LazyByteString
    fromArchive (Archive -> ByteString) -> m Archive -> m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m Archive
    forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferenceDocx
    readDefaultDataFile FilePath
    "reference.pptx" =
      [ByteString] -> ByteString
    B.concat ([ByteString] -> ByteString)
    -> (Archive -> [ByteString]) -> Archive -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [ByteString]
    BL.toChunks (LazyByteString -> [ByteString])
    -> (Archive -> LazyByteString) -> Archive -> [ByteString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Archive -> LazyByteString
    fromArchive (Archive -> ByteString) -> m Archive -> m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m Archive
    forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferencePptx
    readDefaultDataFile FilePath
    "reference.odt" =
      [ByteString] -> ByteString
    B.concat ([ByteString] -> ByteString)
    -> (Archive -> [ByteString]) -> Archive -> ByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . LazyByteString -> [ByteString]
    BL.toChunks (LazyByteString -> [ByteString])
    -> (Archive -> LazyByteString) -> Archive -> [ByteString]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Archive -> LazyByteString
    fromArchive (Archive -> ByteString) -> m Archive -> m ByteString
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m Archive
    forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferenceODT
    readDefaultDataFile FilePath
    fname =
    #ifdef EMBED_DATA_FILES
      case lookup (makeCanonical fname) dataFiles of
        Nothing       -> throwError $ PandocCouldNotFindDataFileError $ T.pack fname
        Just contents -> return contents
    #else
      FilePath -> m FilePath
    forall (m :: * -> *). PandocMonad m => FilePath -> m FilePath
    getDataFileName FilePath
    fname' m FilePath -> (FilePath -> m FilePath) -> m FilePath
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FilePath -> m FilePath
    forall (m :: * -> *). PandocMonad m => FilePath -> m FilePath
    checkExistence m FilePath -> (FilePath -> m ByteString) -> m ByteString
    forall a b. m a -> (a -> m b) -> m b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FilePath -> m ByteString
    forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
    readFileStrict
        where fname' :: FilePath
    fname' = if FilePath
    fname FilePath -> FilePath -> Bool
    forall a. Eq a => a -> a -> Bool
    == FilePath
    "MANUAL.txt" then FilePath
    fname else FilePath
    "data" FilePath -> FilePath -> FilePath
    </> FilePath
    fname

    -- | Returns the input filename unchanged if the file exits, and throws
    -- a `PandocCouldNotFindDataFileError` if it doesn't.
    checkExistence :: PandocMonad m => FilePath -> m FilePath
    checkExistence :: forall (m :: * -> *). PandocMonad m => FilePath -> m FilePath
    checkExistence FilePath
    fn = do
      exists <- FilePath -> m Bool
    forall (m :: * -> *). PandocMonad m => FilePath -> m Bool
    fileExists FilePath
    fn
      if exists
         then return fn
         else throwError $ PandocCouldNotFindDataFileError $ T.pack fn
    #endif

    --- | Read file from user data directory or,
    --- if not found there, from the default data files.
    readDataFile :: PandocMonad m => FilePath -> m B.ByteString
    readDataFile :: forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
    readDataFile FilePath
    fname = do
      datadir <- FilePath -> m (Maybe FilePath)
    forall (m :: * -> *).
    PandocMonad m =>
    FilePath -> m (Maybe FilePath)
    checkUserDataDir FilePath
    fname
      case datadir of
           Maybe FilePath
    Nothing -> FilePath -> m ByteString
    forall (m :: * -> *). PandocMonad m => FilePath -> m ByteString
    readDefaultDataFile FilePath
    fname
           Just FilePath
    userDir -> do
             exists <- FilePath -> m Bool
    forall (m :: * -> *). PandocMonad m => FilePath -> m Bool
    fileExists (FilePath
    userDir FilePath -> FilePath -> FilePath
    </> FilePath
    fname)
             if exists
                then readFileStrict (userDir </> fname)
                else readDefaultDataFile fname

    -- | Retrieve default reference.docx.
    getDefaultReferenceDocx :: PandocMonad m => m Archive
    getDefaultReferenceDocx :: forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferenceDocx = do
      let paths :: [FilePath]
    paths = [FilePath
    "[Content_Types].xml",
                   FilePath
    "_rels/.rels",
                   FilePath
    "docProps/app.xml",
                   FilePath
    "docProps/core.xml",
                   FilePath
    "docProps/custom.xml",
                   FilePath
    "word/document.xml",
                   FilePath
    "word/fontTable.xml",
                   FilePath
    "word/footnotes.xml",
                   FilePath
    "word/comments.xml",
                   FilePath
    "word/numbering.xml",
                   FilePath
    "word/settings.xml",
                   FilePath
    "word/webSettings.xml",
                   FilePath
    "word/styles.xml",
                   FilePath
    "word/_rels/document.xml.rels",
                   FilePath
    "word/_rels/footnotes.xml.rels",
                   FilePath
    "word/theme/theme1.xml"]
      let toLazy :: ByteString -> LazyByteString
    toLazy = [ByteString] -> LazyByteString
    BL.fromChunks ([ByteString] -> LazyByteString)
    -> (ByteString -> [ByteString]) -> ByteString -> LazyByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> [ByteString] -> [ByteString]
    forall a. a -> [a] -> [a]
    :[])
      let pathToEntry :: FilePath -> m Entry
    pathToEntry FilePath
    path = do
            epochtime <- POSIXTime -> Integer
    forall b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (POSIXTime -> Integer)
    -> (UTCTime -> POSIXTime) -> UTCTime -> Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . UTCTime -> POSIXTime
    utcTimeToPOSIXSeconds (UTCTime -> Integer) -> m UTCTime -> m Integer
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m UTCTime
    forall (m :: * -> *). PandocMonad m => m UTCTime
    getTimestamp
            contents <- toLazy <$> readDataFile ("docx/" ++ path)
            return $ toEntry path epochtime contents
      datadir <- m (Maybe FilePath)
    forall (m :: * -> *). PandocMonad m => m (Maybe FilePath)
    getUserDataDir
      mbArchive <- case datadir of
                        Maybe FilePath
    Nothing   -> Maybe FilePath -> m (Maybe FilePath)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe FilePath
    forall a. Maybe a
    Nothing
                        Just FilePath
    d    -> do
                           exists <- FilePath -> m Bool
    forall (m :: * -> *). PandocMonad m => FilePath -> m Bool
    fileExists (FilePath
    d FilePath -> FilePath -> FilePath
    </> FilePath
    "reference.docx")
                           if exists
                              then return (Just (d </> "reference.docx"))
                              else return Nothing
      case mbArchive of
         Just FilePath
    arch -> LazyByteString -> Archive
    toArchive (LazyByteString -> Archive) -> m LazyByteString -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> FilePath -> m LazyByteString
    forall (m :: * -> *). PandocMonad m => FilePath -> m LazyByteString
    readFileLazy FilePath
    arch
         Maybe FilePath
    Nothing   -> (Entry -> Archive -> Archive) -> Archive -> [Entry] -> Archive
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Entry -> Archive -> Archive
    addEntryToArchive Archive
    emptyArchive ([Entry] -> Archive) -> m [Entry] -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                         (FilePath -> m Entry) -> [FilePath] -> m [Entry]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM FilePath -> m Entry
    forall {m :: * -> *}. PandocMonad m => FilePath -> m Entry
    pathToEntry [FilePath]
    paths

    -- | Retrieve default reference.odt.
    getDefaultReferenceODT :: PandocMonad m => m Archive
    getDefaultReferenceODT :: forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferenceODT = do
      let paths :: [FilePath]
    paths = [FilePath
    "mimetype",
                   FilePath
    "manifest.rdf",
                   FilePath
    "styles.xml",
                   FilePath
    "content.xml",
                   FilePath
    "meta.xml",
                   FilePath
    "META-INF/manifest.xml"]
      let pathToEntry :: FilePath -> m Entry
    pathToEntry FilePath
    path = do epochtime <- POSIXTime -> Integer
    forall b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (POSIXTime -> Integer) -> m POSIXTime -> m Integer
    forall a b. (a -> b) -> m a -> m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` m POSIXTime
    forall (m :: * -> *). PandocMonad m => m POSIXTime
    getPOSIXTime
                                contents <- (BL.fromChunks . (:[])) `fmap`
                                              readDataFile ("odt/" ++ path)
                                return $ toEntry path epochtime contents
      datadir <- m (Maybe FilePath)
    forall (m :: * -> *). PandocMonad m => m (Maybe FilePath)
    getUserDataDir
      mbArchive <- case datadir of
                        Maybe FilePath
    Nothing   -> Maybe FilePath -> m (Maybe FilePath)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe FilePath
    forall a. Maybe a
    Nothing
                        Just FilePath
    d    -> do
                           exists <- FilePath -> m Bool
    forall (m :: * -> *). PandocMonad m => FilePath -> m Bool
    fileExists (FilePath
    d FilePath -> FilePath -> FilePath
    </> FilePath
    "reference.odt")
                           if exists
                              then return (Just (d </> "reference.odt"))
                              else return Nothing
      case mbArchive of
         Just FilePath
    arch -> LazyByteString -> Archive
    toArchive (LazyByteString -> Archive) -> m LazyByteString -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> FilePath -> m LazyByteString
    forall (m :: * -> *). PandocMonad m => FilePath -> m LazyByteString
    readFileLazy FilePath
    arch
         Maybe FilePath
    Nothing   -> (Entry -> Archive -> Archive) -> Archive -> [Entry] -> Archive
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Entry -> Archive -> Archive
    addEntryToArchive Archive
    emptyArchive ([Entry] -> Archive) -> m [Entry] -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                         (FilePath -> m Entry) -> [FilePath] -> m [Entry]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM FilePath -> m Entry
    forall {m :: * -> *}. PandocMonad m => FilePath -> m Entry
    pathToEntry [FilePath]
    paths

    -- | Retrieve default reference.pptx.
    getDefaultReferencePptx :: PandocMonad m => m Archive
    getDefaultReferencePptx :: forall (m :: * -> *). PandocMonad m => m Archive
    getDefaultReferencePptx = do
      -- We're going to narrow this down substantially once we get it
      -- working.
      let paths :: [FilePath]
    paths = [ FilePath
    "[Content_Types].xml"
                  , FilePath
    "_rels/.rels"
                  , FilePath
    "docProps/app.xml"
                  , FilePath
    "docProps/core.xml"
                  , FilePath
    "ppt/_rels/presentation.xml.rels"
                  , FilePath
    "ppt/presProps.xml"
                  , FilePath
    "ppt/presentation.xml"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout1.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout2.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout3.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout4.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout5.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout6.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout7.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout8.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout9.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout10.xml.rels"
                  , FilePath
    "ppt/slideLayouts/_rels/slideLayout11.xml.rels"
                  , FilePath
    "ppt/slideLayouts/slideLayout1.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout10.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout11.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout2.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout3.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout4.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout5.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout6.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout7.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout8.xml"
                  , FilePath
    "ppt/slideLayouts/slideLayout9.xml"
                  , FilePath
    "ppt/slideMasters/_rels/slideMaster1.xml.rels"
                  , FilePath
    "ppt/slideMasters/slideMaster1.xml"
                  , FilePath
    "ppt/slides/_rels/slide1.xml.rels"
                  , FilePath
    "ppt/slides/slide1.xml"
                  , FilePath
    "ppt/slides/_rels/slide2.xml.rels"
                  , FilePath
    "ppt/slides/slide2.xml"
                  , FilePath
    "ppt/slides/_rels/slide3.xml.rels"
                  , FilePath
    "ppt/slides/slide3.xml"
                  , FilePath
    "ppt/slides/_rels/slide4.xml.rels"
                  , FilePath
    "ppt/slides/slide4.xml"
                  , FilePath
    "ppt/tableStyles.xml"
                  , FilePath
    "ppt/theme/theme1.xml"
                  , FilePath
    "ppt/viewProps.xml"
                  -- These relate to notes slides.
                  , FilePath
    "ppt/notesMasters/notesMaster1.xml"
                  , FilePath
    "ppt/notesMasters/_rels/notesMaster1.xml.rels"
                  , FilePath
    "ppt/notesSlides/notesSlide1.xml"
                  , FilePath
    "ppt/notesSlides/_rels/notesSlide1.xml.rels"
                  , FilePath
    "ppt/notesSlides/notesSlide2.xml"
                  , FilePath
    "ppt/notesSlides/_rels/notesSlide2.xml.rels"
                  , FilePath
    "ppt/theme/theme2.xml"
                  ]
      let toLazy :: ByteString -> LazyByteString
    toLazy = [ByteString] -> LazyByteString
    BL.fromChunks ([ByteString] -> LazyByteString)
    -> (ByteString -> [ByteString]) -> ByteString -> LazyByteString
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (ByteString -> [ByteString] -> [ByteString]
    forall a. a -> [a] -> [a]
    :[])
      let pathToEntry :: FilePath -> m Entry
    pathToEntry FilePath
    path = do
            epochtime <- POSIXTime -> Integer
    forall b. Integral b => POSIXTime -> b
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (POSIXTime -> Integer) -> m POSIXTime -> m Integer
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> m POSIXTime
    forall (m :: * -> *). PandocMonad m => m POSIXTime
    getPOSIXTime
            contents <- toLazy <$> readDataFile ("pptx/" ++ path)
            return $ toEntry path epochtime contents
      datadir <- m (Maybe FilePath)
    forall (m :: * -> *). PandocMonad m => m (Maybe FilePath)
    getUserDataDir
      mbArchive <- case datadir of
                        Maybe FilePath
    Nothing   -> Maybe FilePath -> m (Maybe FilePath)
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Maybe FilePath
    forall a. Maybe a
    Nothing
                        Just FilePath
    d    -> do
                           exists <- FilePath -> m Bool
    forall (m :: * -> *). PandocMonad m => FilePath -> m Bool
    fileExists (FilePath
    d FilePath -> FilePath -> FilePath
    </> FilePath
    "reference.pptx")
                           if exists
                              then return (Just (d </> "reference.pptx"))
                              else return Nothing
      case mbArchive of
         Just FilePath
    arch -> LazyByteString -> Archive
    toArchive (LazyByteString -> Archive) -> m LazyByteString -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> FilePath -> m LazyByteString
    forall (m :: * -> *). PandocMonad m => FilePath -> m LazyByteString
    readFileLazy FilePath
    arch
         Maybe FilePath
    Nothing   -> (Entry -> Archive -> Archive) -> Archive -> [Entry] -> Archive
    forall a b. (a -> b -> b) -> b -> [a] -> b
    forall (t :: * -> *) a b.
    Foldable t =>
    (a -> b -> b) -> b -> t a -> b
    foldr Entry -> Archive -> Archive
    addEntryToArchive Archive
    emptyArchive ([Entry] -> Archive) -> m [Entry] -> m Archive
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                         (FilePath -> m Entry) -> [FilePath] -> m [Entry]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM FilePath -> m Entry
    forall {m :: * -> *}. PandocMonad m => FilePath -> m Entry
    pathToEntry [FilePath]
    paths

    getDataFileNames :: IO [FilePath]
    getDataFileNames :: IO [FilePath]
    getDataFileNames = do
    #ifdef EMBED_DATA_FILES
      let allDataFiles = map fst dataFiles
    #else
      allDataFiles <- (FilePath -> Bool) -> [FilePath] -> [FilePath]
    forall a. (a -> Bool) -> [a] -> [a]
    filter (\FilePath
    x -> FilePath
    x FilePath -> FilePath -> Bool
    forall a. Eq a => a -> a -> Bool
    /= FilePath
    "." Bool -> Bool -> Bool
    && FilePath
    x FilePath -> FilePath -> Bool
    forall a. Eq a => a -> a -> Bool
    /= FilePath
    "..") ([FilePath] -> [FilePath]) -> IO [FilePath] -> IO [FilePath]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$>
                          (IO FilePath
    getDataDir IO FilePath -> (FilePath -> IO [FilePath]) -> IO [FilePath]
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= FilePath -> IO [FilePath]
    getDirectoryContents)
    #endif
      return $ "reference.docx" : "reference.odt" : "reference.pptx" : allDataFiles

    -- | Return appropriate user data directory for platform.  We use
    -- XDG_DATA_HOME (or its default value), but for backwards compatibility,
    -- we fall back to the legacy user data directory ($HOME/.pandoc on *nix)
    -- if the XDG_DATA_HOME is missing and this exists.  If neither directory
    -- is present, we return the XDG data directory.  If the XDG data directory
    -- is not defined (e.g. because we are in an environment where $HOME is
    -- not defined), we return the empty string.
    defaultUserDataDir :: IO FilePath
    defaultUserDataDir :: IO FilePath
    defaultUserDataDir = do
      xdgDir <- IO FilePath -> (SomeException -> IO FilePath) -> IO FilePath
    forall e a. Exception e => IO a -> (e -> IO a) -> IO a
    E.catch (XdgDirectory -> FilePath -> IO FilePath
    getXdgDirectory XdgDirectory
    XdgData FilePath
    "pandoc")
                   (\(SomeException
    _ :: E.SomeException) -> FilePath -> IO FilePath
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return FilePath
    forall a. Monoid a => a
    mempty)
      xdgExists <- doesDirectoryExist xdgDir
      legacyDir <- E.catch (getAppUserDataDirectory "pandoc")
                    (\(SomeException
    _ :: E.SomeException) -> FilePath -> IO FilePath
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return FilePath
    forall a. Monoid a => a
    mempty)
      legacyDirExists <- doesDirectoryExist legacyDir
      if not xdgExists && legacyDirExists
         then return legacyDir
         else return xdgDir