From ac6dfe0b4efb601f24e444ac8a4059c4103881ef Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Mon, 21 Nov 2016 15:32:27 +0100
Subject: [PATCH] Changed resolution of filter paths.

- We now first treat the argument of `--filter` as a full (absolute
  or relative) path, looking for a program there.  If it's found,
  we run it.
- If not, and if it is a simple program name or a relative path,
  we try resolving it relative to `$DATADIR/filters`.
- If this fails, then we treat it as a program name and look in
  the user's PATH.

Previously if you did `--filter foo` and you had `foo` in your
path and also an executable `foo` in your working directory,
the one in the path would be used. Now the one in the working
directory is used.

In addition, when you do `--filter foo/bar.hs`, pandoc will now
find a filter `$DATADIR/filters/foo/bar.hs` -- assuming there
isn't a `foo/bar.hs` relative to the working directory.

@jkr note the slight revision of what we had before.
This was motivated by the idea that one might clone filter
repositories into the filters subdirectory; it is nice to
be able to run them as `reponame/filtername`.
---
 MANUAL.txt |  8 +-------
 pandoc.hs  | 27 +++++++++++++++------------
 2 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/MANUAL.txt b/MANUAL.txt
index 379c61ca5..0a6362e2e 100644
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -426,7 +426,7 @@ Reader options
     footnotes and links will not work across files. Reading binary
     files (docx, odt, epub) implies `--file-scope`.
 
-`--filter=`*EXECUTABLE*
+`--filter=`*PROGRAM*
 
 :   Specify an executable to be used as a filter transforming the
     pandoc AST after the input is parsed and before the output is
@@ -450,12 +450,6 @@ Reader options
     pandoc filter libraries in [PHP], [perl], and
     [javascript/node.js].
 
-    If no directory is provided pandoc will look for executable or
-    non-executable filters in the director `$DATADIR/filters`, and
-    then for executable filters in the user's `PATH`. If you want to
-    run a script in the working directory, preface the filename with
-    `./`.
-
     In order of preference, pandoc will look for filters in
 
      1. a specified full or relative path (executable or
diff --git a/pandoc.hs b/pandoc.hs
index 80128586a..983089515 100644
--- a/pandoc.hs
+++ b/pandoc.hs
@@ -1111,19 +1111,22 @@ adjustMetadata metadata d = return $ M.foldWithKey setMeta d metadata
 applyTransforms :: [Transform] -> Pandoc -> IO Pandoc
 applyTransforms transforms d = return $ foldr ($) d transforms
 
-  -- First we check to see if a filter is a path. If it isn't, we
-  -- check to see whether it's in `userdir/filters`. If not, we leave
-  -- it unchanged.
+  -- First we check to see if a filter is found.  If not, and if it's
+  -- not an absolute path, we check to see whether it's in `userdir/filters`.
+  -- If not, we leave it unchanged.
 expandFilterPath :: Maybe FilePath -> FilePath -> IO FilePath
-expandFilterPath mbDatadir fp
-  | '/' `elem` fp = return fp
-  | Just datadir <- mbDatadir = do
-      let filterPath = (datadir </> "filters" </> fp)
-      filterPathExists <- doesFileExist filterPath
-      if filterPathExists
-        then return filterPath
-        else return fp
-  | otherwise = return fp
+expandFilterPath mbDatadir fp = do
+  fpExists <- doesFileExist fp
+  if fpExists
+     then return fp
+     else case mbDatadir of
+               Just datadir | isRelative fp -> do
+                 let filterPath = (datadir </> "filters" </> fp)
+                 filterPathExists <- doesFileExist filterPath
+                 if filterPathExists
+                    then return filterPath
+                    else return fp
+               _ -> return fp
 
 applyFilters :: Maybe FilePath -> [FilePath] -> [String] -> Pandoc -> IO Pandoc
 applyFilters mbDatadir filters args d = do