git.iko.soy/typeable/pandoc
on master help sign in
Added --extract-media option.

This has been documented to affect the epub and docx readers, so we should either add the epub reader before the next release or change the documentation.

commitb5210bc175ca7915934082158d4197ab89efa9a2 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 30 Jul 2014, 11:44 (12 years ago) parentb12d2ea
2 files changed+54−17
README+7−1 pandoc.hs+47−16
README+7−1
@@ -318,7 +318,13 @@ Reader options
318318 classes, respectively. The author and time of change is
319319 included. *all* is useful for scripting: only accepting changes
320320 from a certain reviewer, say, or before a certain date. This
321− option only affects the Docx reader.
321+ option only affects the docx reader.
322+
323+`--extract-media=`*DIR*
324+: Extract images and other media contained in a docx or epub container
325+ to the path *DIR*, creating it if necessary, and adjust the images
326+ references in the document so they point to the extracted files.
327+ This option only affects the docx and epub readers.
322328
323329General writer options
324330----------------------
pandoc.hs+47−16
@@ -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