@@ -46,12 +46,11 @@ import qualified Control.Exception as E
4646import Control.Monad
4747import Control.Monad.Except (catchError, throwError)
4848import Control.Monad.Trans
49−import Data.Aeson (defaultOptions, eitherDecode', encode)
49+import Data.Aeson (defaultOptions)
5050import Data.Aeson.TH (deriveJSON)
5151import qualified Data.ByteString as BS
5252import qualified Data.ByteString.Lazy as B
5353import Data.Char (toLower, toUpper)
54−import Data.Foldable (foldrM)
5554import Data.List (find, intercalate, isPrefixOf, isSuffixOf, sort)
5655import qualified Data.Map as M
5756import Data.Maybe (fromMaybe, isJust, isNothing)
@@ -73,10 +72,9 @@ import Skylighting (Style, Syntax (..), defaultSyntaxMap, parseTheme,
7372 pygments)
7473import Skylighting.Parser (addSyntaxDefinition, parseSyntaxDefinition)
7574import System.Console.GetOpt
76−import System.Directory (Permissions (..), doesFileExist, findExecutable,
77− getAppUserDataDirectory, getPermissions)
78−import System.Environment (getArgs, getEnvironment, getProgName)
79−import System.Exit (ExitCode (..), exitSuccess)
75+import System.Directory (getAppUserDataDirectory)
76+import System.Environment (getArgs, getProgName)
77+import System.Exit (exitSuccess)
8078import System.FilePath
8179import System.IO (nativeNewline, stdout)
8280import qualified System.IO as IO (Newline (..))
@@ -84,10 +82,9 @@ import System.IO.Error (isDoesNotExistError)
8482import Text.Pandoc
8583import Text.Pandoc.BCP47 (Lang (..), parseBCP47)
8684import Text.Pandoc.Builder (setMeta, deleteMeta)
85+import Text.Pandoc.Filter (Filter (JSONFilter, LuaFilter), applyFilters)
8786import Text.Pandoc.Highlighting (highlightingStyles)
88−import Text.Pandoc.Lua (LuaException (..), runLuaFilter)
8987import Text.Pandoc.PDF (makePDF)
90−import Text.Pandoc.Process (pipeProcess)
9188import Text.Pandoc.SelfContained (makeDataURI, makeSelfContained)
9289import Text.Pandoc.Shared (eastAsianLineBreakFilter, stripEmptyParagraphs,
9390 headerShift, isURI, ordNub, safeRead, tabFilter)
@@ -538,48 +535,6 @@ type Transform = Pandoc -> Pandoc
538535isTextFormat :: String -> Bool
539536isTextFormat s = s `notElem` ["odt","docx","epub2","epub3","epub","pptx"]
540537
541−externalFilter :: MonadIO m
542− => ReaderOptions -> FilePath -> [String] -> Pandoc -> m Pandoc
543−externalFilter ropts f args' d = liftIO $ do
544− exists <- doesFileExist f
545− isExecutable <- if exists
546− then executable <$> getPermissions f
547− else return True
548− let (f', args'') = if exists
549− then case map toLower (takeExtension f) of
550− _ | isExecutable -> ("." </> f, args')
551− ".py" -> ("python", f:args')
552− ".hs" -> ("runhaskell", f:args')
553− ".pl" -> ("perl", f:args')
554− ".rb" -> ("ruby", f:args')
555− ".php" -> ("php", f:args')
556− ".js" -> ("node", f:args')
557− ".r" -> ("Rscript", f:args')
558− _ -> (f, args')
559− else (f, args')
560− unless (exists && isExecutable) $ do
561− mbExe <- findExecutable f'
562− when (isNothing mbExe) $
563− E.throwIO $ PandocFilterError f ("Could not find executable " ++ f')
564− env <- getEnvironment
565− let env' = Just
566− ( ("PANDOC_VERSION", pandocVersion)
567− : ("PANDOC_READER_OPTIONS", UTF8.toStringLazy (encode ropts))
568− : env )
569− (exitcode, outbs) <- E.handle filterException $
570− pipeProcess env' f' args'' $ encode d
571− case exitcode of
572− ExitSuccess -> either (E.throwIO . PandocFilterError f)
573− return $ eitherDecode' outbs
574− ExitFailure ec -> E.throwIO $ PandocFilterError f
575− ("Filter returned error status " ++ show ec)
576− where filterException :: E.SomeException -> IO a
577− filterException e = E.throwIO $ PandocFilterError f (show e)
578−
579−data Filter = LuaFilter FilePath
580− | JSONFilter FilePath
581− deriving (Show)
582−
583538-- | Data structure for command line options.
584539data Opt = Opt
585540 { optTabStop :: Int -- ^ Number of spaces per tab
@@ -824,50 +779,6 @@ defaultWriterName x =
824779applyTransforms :: Monad m => [Transform] -> Pandoc -> m Pandoc
825780applyTransforms transforms d = return $ foldr ($) d transforms
826781
827− -- First we check to see if a filter is found. If not, and if it's
828− -- not an absolute path, we check to see whether it's in `userdir/filters`.
829− -- If not, we leave it unchanged.
830−expandFilterPath :: PandocMonad m => FilePath -> m FilePath
831−expandFilterPath fp = do
832− mbDatadir <- getUserDataDir
833− fpExists <- fileExists fp
834− if fpExists
835− then return fp
836− else case mbDatadir of
837− Just datadir | isRelative fp -> do
838− let filterPath = datadir </> "filters" </> fp
839− filterPathExists <- fileExists filterPath
840− if filterPathExists
841− then return filterPath
842− else return fp
843− _ -> return fp
844−
845−applyFilters :: ReaderOptions
846− -> [Filter]
847− -> [String]
848− -> Pandoc
849− -> PandocIO Pandoc
850−applyFilters ropts filters args d = do
851− foldrM ($) d $ map (applyFilter ropts args) filters
852−
853−applyFilter :: ReaderOptions
854− -> [String]
855− -> Filter
856− -> Pandoc
857− -> PandocIO Pandoc
858−applyFilter ropts args (LuaFilter f) d = do
859− f' <- expandFilterPath f
860− let format = case args of
861− (x:_) -> x
862− _ -> error "Format not supplied for lua filter"
863− res <- runLuaFilter ropts f' format d
864− case res of
865− Right x -> return x
866− Left (LuaException s) -> E.throw (PandocFilterError f s)
867−applyFilter ropts args (JSONFilter f) d = do
868− f' <- expandFilterPath f
869− liftIO $ externalFilter ropts f' args d
870−
871782readSource :: FilePath -> PandocIO Text
872783readSource "-" = liftIO (UTF8.toText <$> BS.getContents)
873784readSource src = case parseURI src of
@@ -1722,5 +1633,4 @@ deprecatedOption o msg =
17221633-- see https://github.com/jgm/pandoc/pull/4083
17231634-- using generic deriving caused long compilation times
17241635$(deriveJSON defaultOptions ''LineEnding)
1725−$(deriveJSON defaultOptions ''Filter)
17261636$(deriveJSON defaultOptions ''Opt)