@@ -78,8 +78,6 @@ import Codec.Archive.Zip
7878import Text.Pandoc.Definition
7979import Text.Pandoc.Options
8080import Text.Pandoc.Builder (text, toList)
81−import Text.Pandoc.MIME (getMimeType)
82−import Text.Pandoc.UTF8 (toString)
8381import Text.Pandoc.Walk
8482import Text.Pandoc.Readers.Docx.Parse
8583import Text.Pandoc.Readers.Docx.Lists
@@ -88,9 +86,7 @@ import Text.Pandoc.Readers.Docx.TexChar
8886import Text.Pandoc.Shared
8987import Data.Maybe (mapMaybe, fromMaybe)
9088import Data.List (delete, isPrefixOf, (\\), intercalate, intersect)
91−import qualified Data.ByteString as BS
9289import qualified Data.ByteString.Lazy as B
93−import Data.ByteString.Base64 (encode)
9490import qualified Data.Map as M
9591import Control.Monad.Reader
9692import Control.Monad.State
@@ -98,17 +94,24 @@ import Text.Printf (printf)
9894
9995readDocx :: ReaderOptions
10096 -> B.ByteString
101− -> Pandoc
97+ -> (Pandoc, MediaBag)
10298readDocx opts bytes =
10399 case archiveToDocx (toArchive bytes) of
104− Right docx -> Pandoc meta blks where
105− (meta, blks) = (docxToMetaAndBlocks opts docx)
100+ Right docx -> (Pandoc meta blks, mediaBag) where
101+ (meta, blks, mediaBag) = (docxToOutput opts docx)
106102 Left _ -> error $ "couldn't parse docx file"
107103
108104data DState = DState { docxAnchorMap :: M.Map String String
105+ , docxMediaBag :: MediaBag
109106 , docxInHeaderBlock :: Bool
110107 , docxInTexSubscript :: Bool }
111108
109+defaultDState :: DState
110+defaultDState = DState { docxAnchorMap = M.empty
111+ , docxMediaBag = M.empty
112+ , docxInHeaderBlock = False
113+ , docxInTexSubscript = False}
114+
112115data DEnv = DEnv { docxOptions :: ReaderOptions
113116 , docxDocument :: Docx}
114117
@@ -319,13 +322,6 @@ runToInlines (Footnote bps) =
319322runToInlines (Endnote bps) =
320323 concatMapM bodyPartToBlocks bps >>= (\blks -> return [Note blks])
321324
322−makeDataUrl :: String -> B.ByteString -> Maybe String
323−makeDataUrl fp bs =
324− case getMimeType fp of
325− Just mime -> Just $ "data:" ++ mime ++ ";base64," ++
326− toString (encode $ BS.concat $ B.toChunks bs)
327− Nothing -> Nothing
328−
329325parPartToInlines :: ParPart -> DocxContext [Inline]
330326parPartToInlines (PlainRun r) = runToInlines r
331327parPartToInlines (Insertion _ author date runs) = do
@@ -372,11 +368,9 @@ parPartToInlines (BookMark _ anchor) =
372368 modify $ \s -> s { docxAnchorMap = M.insert anchor newAnchor anchorMap}
373369 return [Span (newAnchor, ["anchor"], []) []]
374370parPartToInlines (Drawing fp bs) = do
375− return $ case True of -- TODO: add self-contained images
376− True -> [Image [] (fp, "")]
377− False -> case makeDataUrl fp bs of
378− Just d -> [Image [] (d, "")]
379− Nothing -> [Image [] ("", "")]
371+ mediaBag <- gets docxMediaBag
372+ modify $ \s -> s { docxMediaBag = M.insert fp bs mediaBag}
373+ return [Image [] (fp, "")]
380374parPartToInlines (InternalHyperLink anchor runs) = do
381375 ils <- concatMapM runToInlines runs
382376 return [Link ils ('#' : anchor, "")]
@@ -675,26 +669,25 @@ rewriteLink l@(Link ils ('#':target, title)) = do
675669 Nothing -> l
676670rewriteLink il = return il
677671
678−bodyToMetaAndBlocks :: Body -> DocxContext (Meta, [Block])
679−bodyToMetaAndBlocks (Body bps) = do
672+bodyToOutput :: Body -> DocxContext (Meta, [Block], MediaBag)
673+bodyToOutput (Body bps) = do
680674 let (metabps, blkbps) = sepBodyParts bps
681675 meta <- bodyPartsToMeta metabps
682676 blks <- concatMapM bodyPartToBlocks blkbps >>=
683677 walkM rewriteLink
684− return $
685− (meta,
686− blocksToDefinitions $
687− blocksToBullets $ blks)
688−
689−docxToMetaAndBlocks :: ReaderOptions -> Docx -> (Meta, [Block])
690−docxToMetaAndBlocks opts d@(Docx (Document _ body)) =
691− let dState = DState { docxAnchorMap = M.empty
692− , docxInHeaderBlock = False
693− , docxInTexSubscript = False}
678+ mediaBag <- gets docxMediaBag
679+ return $ (meta,
680+ blocksToDefinitions $ blocksToBullets $ blks,
681+ mediaBag)
682+
683+docxToOutput :: ReaderOptions -> Docx -> (Meta, [Block], MediaBag)
684+docxToOutput opts d@(Docx (Document _ body)) =
685+ let dState = defaultDState
694686 dEnv = DEnv { docxOptions = opts
695687 , docxDocument = d}
696688 in
697− evalDocxContext (bodyToMetaAndBlocks body) dEnv dState
689+ evalDocxContext (bodyToOutput body) dEnv dState
690+
698691
699692ilToCode :: Inline -> String
700693ilToCode (Str s) = s