From df0d3fb78cd5d0457c791bbd3b132dd284bfe49c Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Thu, 19 Dec 2024 10:17:58 -0800 Subject: [PATCH] Change `--template` to allow use of extensionless templates. The intent is to allow bash process substitution: e.g., `--template <(echo "foo")`. Previously pandoc *always* added an extension based on the output format, which caused problems with the absolute filenames used by bash process substitution (e.g. `/dev/fd/11`). Now, if the template has no extension, pandoc will first try to find it without the extension, and then add the extension if it can't be found. So, in general, extensionless templates can now be used. But this has been implemented in a way that should not cause problems for existing uses, unless you are using a template `NAME.FORMAT` but happen to have an extensionless file `NAME` in the template search path. Closes #5270. --- MANUAL.txt | 18 ++++++++++-------- src/Text/Pandoc/App/OutputSettings.hs | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/MANUAL.txt b/MANUAL.txt index 14ea6e2165af..c6770da0472d 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -761,14 +761,16 @@ header when requesting a document from a URL: `--template=`*FILE*|*URL* : Use the specified file as a custom template for the generated document. - Implies `--standalone`. See [Templates], below, for a description - of template syntax. If no extension is specified, an extension - corresponding to the writer will be added, so that `--template=special` - looks for `special.html` for HTML output. If the template is not - found, pandoc will search for it in the `templates` subdirectory of - the user data directory (see `--data-dir`). If this option is not used, - a default template appropriate for the output format will be used (see - `-D/--print-default-template`). + Implies `--standalone`. See [Templates], below, for a + description of template syntax. If the template is not found, + pandoc will search for it in the `templates` subdirectory of + the user data directory (see `--data-dir`). If no extension + is specified and an extensionless template is not found, + pandoc will look for a template with an extension + corresponding to the writer, so that `--template=special` + looks for `special.html` for HTML output. If this option is + not used, a default template appropriate for the output + format will be used (see `-D/--print-default-template`). `-V` *KEY*[`=`*VAL*], `--variable=`*KEY*[`:`*VAL*] diff --git a/src/Text/Pandoc/App/OutputSettings.hs b/src/Text/Pandoc/App/OutputSettings.hs index f8c27bee4902..38cd35455ba6 100644 --- a/src/Text/Pandoc/App/OutputSettings.hs +++ b/src/Text/Pandoc/App/OutputSettings.hs @@ -25,7 +25,7 @@ import qualified Data.Text as T import Text.DocTemplates (toVal, Context(..), Val(..)) import qualified Control.Exception as E import Control.Monad -import Control.Monad.Except (throwError) +import Control.Monad.Except (throwError, catchError) import Control.Monad.Trans import Data.Char (toLower) import Data.List (find) @@ -111,13 +111,15 @@ optToOutputSettings scriptingEngine opts = do _ | not standalone -> return Nothing Nothing -> Just <$> getDefault Just tp -> do - -- strip off extensions - let tp' = case takeExtension tp of - "" -> tp <.> T.unpack format - _ -> tp - getTemplate tp' - >>= runWithPartials . compileTemplate tp' - >>= fmap Just . templateOrThrow + let getAndCompile fp = + getTemplate fp >>= runWithPartials . compileTemplate fp >>= + fmap Just . templateOrThrow + catchError + (getAndCompile tp) + (\e -> + if null (takeExtension tp) + then getAndCompile (tp <.> T.unpack format) + else throwError e) (writer, writerExts, mtemplate) <- if "lua" `T.isSuffixOf` format