@@ -33,6 +33,7 @@ module Main where
3333import Text.Pandoc
3434import Text.Pandoc.Builder (setMeta)
3535import Text.Pandoc.PDF (makePDF)
36+import Text.Pandoc.Walk (walk)
3637import Text.Pandoc.Readers.LaTeX (handleIncludes)
3738import Text.Pandoc.Shared ( tabFilter, readDataFileUTF8, readDataFile,
3839 safeRead, headerShift, normalize, err, warn,
@@ -49,7 +50,8 @@ import System.Console.GetOpt
4950import Data.Char ( toLower )
5051import Data.List ( intercalate, isPrefixOf, isSuffixOf, sort )
5152import System.Directory ( getAppUserDataDirectory, findExecutable,
52− doesFileExist, Permissions(..), getPermissions )
53+ doesFileExist, Permissions(..), getPermissions,
54+ createDirectoryIfMissing )
5355import System.IO ( stdout, stderr )
5456import System.IO.Error ( isDoesNotExistError )
5557import qualified Control.Exception as E
@@ -182,6 +184,7 @@ data Opt = Opt
182184 , optAscii :: Bool -- ^ Use ascii characters only in html
183185 , optTeXLigatures :: Bool -- ^ Use TeX ligatures for quotes/dashes
184186 , optDefaultImageExtension :: String -- ^ Default image extension
187+ , optExtractMedia :: Maybe FilePath -- ^ Path to extract embedded media
185188 , optTrace :: Bool -- ^ Print debug information
186189 , optTrackChanges :: TrackChanges -- ^ Accept or reject MS Word track-changes.
187190 }
@@ -239,6 +242,7 @@ defaultOpts = Opt
239242 , optAscii = False
240243 , optTeXLigatures = True
241244 , optDefaultImageExtension = ""
245+ , optExtractMedia = Nothing
242246 , optTrace = False
243247 , optTrackChanges = AcceptChanges
244248 }
@@ -343,6 +347,26 @@ options =
343347 "NUMBER")
344348 "" -- "Tab stop (default 4)"
345349
350+ , Option "" ["track-changes"]
351+ (ReqArg
352+ (\arg opt -> do
353+ action <- case arg of
354+ "accept" -> return AcceptChanges
355+ "reject" -> return RejectChanges
356+ "all" -> return AllChanges
357+ _ -> err 6
358+ ("Unknown option for track-changes: " ++ arg)
359+ return opt { optTrackChanges = action })
360+ "accept|reject|all")
361+ "" -- "Accepting or reject MS Word track-changes.""
362+
363+ , Option "" ["extract-media"]
364+ (ReqArg
365+ (\arg opt -> do
366+ return opt { optExtractMedia = Just arg })
367+ "PATH")
368+ "" -- "Directory to which to extract embedded media"
369+
346370 , Option "s" ["standalone"]
347371 (NoArg
348372 (\opt -> return opt { optStandalone = True }))
@@ -787,19 +811,6 @@ options =
787811 (\opt -> return opt { optTrace = True }))
788812 "" -- "Turn on diagnostic tracing in readers."
789813
790− , Option "" ["track-changes"]
791− (ReqArg
792− (\arg opt -> do
793− action <- case arg of
794− "accept" -> return AcceptChanges
795− "reject" -> return RejectChanges
796− "all" -> return AllChanges
797− _ -> err 6
798− ("Unknown option for track-changes: " ++ arg)
799− return opt { optTrackChanges = action })
800− "accept|reject|all")
801− "" -- "Accepting or reject MS Word track-changes.""
802−
803814 , Option "" ["dump-args"]
804815 (NoArg
805816 (\opt -> return opt { optDumpArgs = True }))
@@ -998,6 +1009,7 @@ main = do
9981009 , optAscii = ascii
9991010 , optTeXLigatures = texLigatures
10001011 , optDefaultImageExtension = defaultImageExtension
1012+ , optExtractMedia = mbExtractMedia
10011013 , optTrace = trace
10021014 , optTrackChanges = trackChanges
10031015 } = opts
@@ -1196,13 +1208,32 @@ main = do
11961208 then handleIncludes
11971209 else return
11981210
1211+ let writeMedia :: FilePath -> (FilePath, B.ByteString) -> IO ()
1212+ writeMedia dir (subpath, bs) = do
1213+ -- we join and split to convert a/b/c to a\b\c on Windows;
1214+ -- in zip containers all paths use /
1215+ let fullpath = dir </> joinPath (splitPath subpath)
1216+ createDirectoryIfMissing True $ takeDirectory fullpath
1217+ warn $ "extracting " ++ fullpath
1218+ B.writeFile fullpath bs
1219+
1220+ let adjustImagePath :: FilePath -> [FilePath] -> Inline -> Inline
1221+ adjustImagePath dir paths (Image lab (src, tit))
1222+ | src `elem` paths = Image lab (dir ++ "/" ++ src, tit)
1223+ adjustImagePath _ _ x = x
1224+
11991225 doc <- case reader of
12001226 StringReader r->
12011227 readSources sources >>=
12021228 handleIncludes' . convertTabs . intercalate "\n" >>=
12031229 r readerOpts
1204− ByteStringReader r -> readFiles sources >>= r readerOpts >>=
1205− (return . fst)
1230+ ByteStringReader r -> do
1231+ (d, media) <- readFiles sources >>= r readerOpts
1232+ case mbExtractMedia of
1233+ Just dir | not (M.null media) -> do
1234+ mapM_ (writeMedia dir) $ M.toList media
1235+ return $ walk (adjustImagePath dir (M.keys media)) d
1236+ _ -> return d
12061237
12071238
12081239 let doc0 = M.foldWithKey setMeta doc metadata