From 7df29e495f17b239f0e4b239fda849a1f27d2cf2 Mon Sep 17 00:00:00 2001 From: Even Brenden <evenbrenden@gmail.com> Date: Fri, 21 Jan 2022 21:00:45 +0100 Subject: [PATCH] Search for metadata files in $DATADIR/metadata (#7851) If files specified with `--metadata-file` are not found in the working directory, look in `$DATADIR/metadata`. Expose new `readMetadataFile` function from Text.Pandoc.Class [API change]. Expose new `PandocCouldNotFindMetadataFileError` constructor for `PandocError` from Text.Pandoc.Error [API change]. Closes #5876. --- MANUAL.txt | 5 +- pandoc.cabal | 3 + src/Text/Pandoc/App.hs | 2 +- src/Text/Pandoc/Class/PandocMonad.hs | 20 +++++++ src/Text/Pandoc/Error.hs | 4 ++ test/command/5876.md | 58 ++++++++++++++++++++ test/command/5876.yaml | 3 + test/command/5876/metadata/5876.yaml | 3 + test/command/5876/metadata/command/5876.yaml | 3 + 9 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 test/command/5876.md create mode 100644 test/command/5876.yaml create mode 100644 test/command/5876/metadata/5876.yaml create mode 100644 test/command/5876/metadata/command/5876.yaml diff --git a/MANUAL.txt b/MANUAL.txt index fd5834491..6b688f8c1 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -644,7 +644,9 @@ header when requesting a document from a URL: files specified later on the command line will be preferred over those specified in earlier files. Metadata values specified inside the document, or by using `-M`, overwrite - values specified with this option. + values specified with this option. The file will be searched + for first in the working directory, and then in the `metadata` + subdirectory of the user data directory (see `--data-dir`). `-p`, `--preserve-tabs` @@ -1512,6 +1514,7 @@ Nonzero exit codes have the following meanings: 93 PandocIpynbDecodingError 94 PandocUnsupportedCharsetError 97 PandocCouldNotFindDataFileError + 98 PandocCouldNotFindMetadataFileError 99 PandocResourceNotFound ----- ------------------------------------ diff --git a/pandoc.cabal b/pandoc.cabal index 134c31fc1..851df99d9 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -251,6 +251,9 @@ extra-source-files: test/command/3510-export.latex test/command/3510-src.hs test/command/3971b.tex + test/command/5876.yaml + test/command/5876/metadata/5876.yaml + test/command/5876/metadata/command/5876.yaml test/docbook-chapter.docbook test/docbook-reader.docbook test/docbook-xref.docbook diff --git a/src/Text/Pandoc/App.hs b/src/Text/Pandoc/App.hs index 3ddc4c761..b17fdd178 100644 --- a/src/Text/Pandoc/App.hs +++ b/src/Text/Pandoc/App.hs @@ -219,7 +219,7 @@ convertWithOpts opts = do case optMetadataFiles opts of [] -> return mempty paths -> mconcat <$> - mapM (\path -> do raw <- readFileStrict path + mapM (\path -> do raw <- readMetadataFile path yamlToMeta readerOpts (Just path) raw) paths let transforms = (case optShiftHeadingLevelBy opts of diff --git a/src/Text/Pandoc/Class/PandocMonad.hs b/src/Text/Pandoc/Class/PandocMonad.hs index c15ce6444..144a13ba4 100644 --- a/src/Text/Pandoc/Class/PandocMonad.hs +++ b/src/Text/Pandoc/Class/PandocMonad.hs @@ -46,6 +46,7 @@ module Text.Pandoc.Class.PandocMonad , getResourcePath , readDefaultDataFile , readDataFile + , readMetadataFile , fillMediaBag , toLang , setTranslations @@ -586,6 +587,25 @@ readDataFile fname = do then readFileStrict (userDir </> fname) else readDefaultDataFile fname +-- | Read metadata file from the working directory or, if not found there, from +-- the metadata subdirectory of the user data directory. +readMetadataFile :: PandocMonad m => FilePath -> m B.ByteString +readMetadataFile fname = do + existsInWorkingDir <- fileExists fname + if existsInWorkingDir + then readFileStrict fname + else do + dataDir <- getUserDataDir + case dataDir of + Nothing -> + throwError $ PandocCouldNotFindMetadataFileError $ T.pack fname + Just userDir -> do + let path = userDir </> "metadata" </> fname + existsInUserDir <- fileExists path + if existsInUserDir + then readFileStrict path + else throwError $ PandocCouldNotFindMetadataFileError $ T.pack fname + -- | Read file from from the default data files. readDefaultDataFile :: PandocMonad m => FilePath -> m B.ByteString readDefaultDataFile "reference.docx" = diff --git a/src/Text/Pandoc/Error.hs b/src/Text/Pandoc/Error.hs index 684a6a884..3e2479d61 100644 --- a/src/Text/Pandoc/Error.hs +++ b/src/Text/Pandoc/Error.hs @@ -54,6 +54,7 @@ data PandocError = PandocIOError Text IOError | PandocFilterError Text Text | PandocLuaError Text | PandocCouldNotFindDataFileError Text + | PandocCouldNotFindMetadataFileError Text | PandocResourceNotFound Text | PandocTemplateError Text | PandocAppError Text @@ -118,6 +119,8 @@ renderError e = PandocLuaError msg -> "Error running Lua:\n" <> msg PandocCouldNotFindDataFileError fn -> "Could not find data file " <> fn + PandocCouldNotFindMetadataFileError fn -> + "Could not find metadata file " <> fn PandocResourceNotFound fn -> "File " <> fn <> " not found in resource path" PandocTemplateError s -> "Error compiling template " <> s @@ -198,6 +201,7 @@ handleError (Left e) = PandocIpynbDecodingError{} -> 93 PandocUnsupportedCharsetError{} -> 94 PandocCouldNotFindDataFileError{} -> 97 + PandocCouldNotFindMetadataFileError{} -> 98 PandocResourceNotFound{} -> 99 err :: Int -> Text -> IO a diff --git a/test/command/5876.md b/test/command/5876.md new file mode 100644 index 000000000..7671a89cf --- /dev/null +++ b/test/command/5876.md @@ -0,0 +1,58 @@ +``` +% pandoc -s -t native --data-dir=command/5876 --metadata-file=5876.yaml +Hello +^D +Pandoc + Meta + { unMeta = + fromList + [ ( "desc" + , MetaInlines + [ Str "Found" + , Space + , Str "in" + , Space + , Str "metadata" + , Space + , Str "directory." + ] + ) + ] + } + [ Para [ Str "Hello" ] ] +``` +``` +% pandoc -s -t native --data-dir=command/5876 --metadata-file=command/5876.yaml +Hello +^D +Pandoc + Meta + { unMeta = + fromList + [ ( "desc" + , MetaInlines + [ Str "Found" + , Space + , Str "in" + , Space + , Str "working" + , Space + , Str "directory." + ] + ) + ] + } + [ Para [ Str "Hello" ] ] +``` +``` +% pandoc -s -t native --data-dir=command/5876 --metadata-file=does-not-exist.yaml +Hello +^D +Could not find metadata file does-not-exist.yaml +``` +``` +% pandoc -s -t native --metadata-file=does-not-exist.yaml +Hello +^D +Could not find metadata file does-not-exist.yaml +``` diff --git a/test/command/5876.yaml b/test/command/5876.yaml new file mode 100644 index 000000000..9e6604922 --- /dev/null +++ b/test/command/5876.yaml @@ -0,0 +1,3 @@ +--- +desc: Found in working directory. +--- diff --git a/test/command/5876/metadata/5876.yaml b/test/command/5876/metadata/5876.yaml new file mode 100644 index 000000000..d52de910f --- /dev/null +++ b/test/command/5876/metadata/5876.yaml @@ -0,0 +1,3 @@ +--- +desc: Found in metadata directory. +--- diff --git a/test/command/5876/metadata/command/5876.yaml b/test/command/5876/metadata/command/5876.yaml new file mode 100644 index 000000000..6bb46d51e --- /dev/null +++ b/test/command/5876/metadata/command/5876.yaml @@ -0,0 +1,3 @@ +--- +desc: Should not be loaded. +---