@@ -1,5 +1,6 @@
1{-# LANGUAGE DeriveFunctor, DeriveDataTypeable, TypeSynonymInstances,
1{-# LANGUAGE DeriveFunctor, DeriveDataTypeable, TypeSynonymInstances,
2−FlexibleInstances, GeneralizedNewtypeDeriving, FlexibleContexts #-}
2+FlexibleInstances, GeneralizedNewtypeDeriving, FlexibleContexts,
5Copyright (C) 2016 Jesse Rosenthal <jrosenthal@jhu.edu>
6Copyright (C) 2016 Jesse Rosenthal <jrosenthal@jhu.edu>
@@ -50,6 +51,8 @@ module Text.Pandoc.Class ( PandocMonad(..)
50 , fetchItem
51 , fetchItem
51 , getInputFiles
52 , getInputFiles
52 , getOutputFile
53 , getOutputFile
53 , PandocIO(..)
56 , PandocIO(..)
54 , PandocPure(..)
57 , PandocPure(..)
55 , FileTree(..)
58 , FileTree(..)
@@ -88,7 +91,7 @@ import qualified Data.ByteString as B
88import qualified Data.ByteString.Lazy as BL
91import qualified Data.ByteString.Lazy as BL
89import qualified System.Environment as IO (lookupEnv)
92import qualified System.Environment as IO (lookupEnv)
90import System.FilePath.Glob (match, compile)
93import System.FilePath.Glob (match, compile)
91−import System.FilePath ((</>), takeExtension, dropExtension)
94+import System.FilePath ((</>), takeExtension, dropExtension, isRelative)
92import qualified System.FilePath.Glob as IO (glob)
95import qualified System.FilePath.Glob as IO (glob)
93import qualified System.Directory as IO (getModificationTime)
96import qualified System.Directory as IO (getModificationTime)
94import Control.Monad as M (fail)
97import Control.Monad as M (fail)
@@ -165,6 +168,12 @@ getInputFiles = getsCommonState stInputFiles
165getOutputFile :: PandocMonad m => m (Maybe FilePath)
168getOutputFile :: PandocMonad m => m (Maybe FilePath)
166getOutputFile = getsCommonState stOutputFile
169getOutputFile = getsCommonState stOutputFile
171+setResourcePath :: PandocMonad m => [FilePath] -> m ()
172+setResourcePath ps = modifyCommonState $ \st -> st{stResourcePath = ps}
174+getResourcePath :: PandocMonad m => m [FilePath]
175+getResourcePath = getsCommonState stResourcePath
168getPOSIXTime :: (PandocMonad m) => m POSIXTime
177getPOSIXTime :: (PandocMonad m) => m POSIXTime
169getPOSIXTime = utcTimeToPOSIXSeconds <$> getCurrentTime
178getPOSIXTime = utcTimeToPOSIXSeconds <$> getCurrentTime
@@ -183,11 +192,12 @@ readFileFromDirs (d:ds) f = catchError
186−data CommonState = CommonState { stLog :: [LogMessage]
195+data CommonState = CommonState { stLog :: [LogMessage]
187− , stMediaBag :: MediaBag
196+ , stMediaBag :: MediaBag
188− , stInputFiles :: Maybe [FilePath]
197+ , stInputFiles :: Maybe [FilePath]
189− , stOutputFile :: Maybe FilePath
198+ , stOutputFile :: Maybe FilePath
199+ , stResourcePath :: [FilePath]
190− , stVerbosity :: Verbosity
200+ , stVerbosity :: Verbosity
193instance Default CommonState where
203instance Default CommonState where
@@ -195,6 +205,7 @@ instance Default CommonState where
195 , stMediaBag = mempty
205 , stMediaBag = mempty
196 , stInputFiles = Nothing
206 , stInputFiles = Nothing
197 , stOutputFile = Nothing
207 , stOutputFile = Nothing
208+ , stResourcePath = ["."]
198 , stVerbosity = WARNING
209 , stVerbosity = WARNING
@@ -289,7 +300,10 @@ downloadOrRead sourceURL s = do
289 readLocalFile $ dropWhile (=='/') (uriPath u')
300 readLocalFile $ dropWhile (=='/') (uriPath u')
290 _ -> readLocalFile fp -- get from local file system
301 _ -> readLocalFile fp -- get from local file system
291 where readLocalFile f = do
302 where readLocalFile f = do
303+ resourcePath <- getResourcePath
304+ cont <- if isRelative f
305+ then withPaths resourcePath readFileStrict f
292− cont <- readFileStrict f
306+ else readFileStrict f
293 return (cont, mime)
307 return (cont, mime)
294 httpcolon = URI{ uriScheme = "http:",
308 httpcolon = URI{ uriScheme = "http:",
295 uriAuthority = Nothing,
309 uriAuthority = Nothing,
@@ -306,6 +320,16 @@ downloadOrRead sourceURL s = do
306 convertSlash '\\' = '/'
320 convertSlash '\\' = '/'
307 convertSlash x = x
321 convertSlash x = x
323+withPaths :: PandocMonad m => [FilePath] -> (FilePath -> m a) -> FilePath -> m a
324+withPaths [] _ fp = throwError $ PandocIOError fp
325+ (userError "file not found in resource path")
326+withPaths (p:ps) action fp =
327+ catchError (do res <- action (p </> fp)
329+ report $ UsingResourceFrom fp p
331+ (\_ -> withPaths ps action fp)
309data PureState = PureState { stStdGen :: StdGen
333data PureState = PureState { stStdGen :: StdGen
310 , stWord8Store :: [Word8] -- should be
334 , stWord8Store :: [Word8] -- should be
311 -- inifinite,
335 -- inifinite,