diff options
author | John MacFarlane <jgm@berkeley.edu> | 2011-07-17 23:21:59 -0700 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2011-07-17 23:21:59 -0700 |
commit | e2aec87956762768c5ec7759ec0725c12648dfff (patch) | |
tree | 75e35735b0c3435f08c29b37e0136d0c48b160f0 /src/Text | |
parent | cc2042147188734f6f5f8e34c33dfcbff13ce0d5 (diff) | |
download | pandoc-e2aec87956762768c5ec7759ec0725c12648dfff.tar.gz |
ODT writer: Construct META-INF/manifest.xml based on archive contents.
This fixes a bug in ODTs containing images. LibreOffice would signal
that these ODTs were corrupt, because the manifest.xml did not contain
a reference to the image files.
Diffstat (limited to 'src/Text')
-rw-r--r-- | src/Text/Pandoc/Writers/ODT.hs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/Text/Pandoc/Writers/ODT.hs b/src/Text/Pandoc/Writers/ODT.hs index 908df1163..4cdfed6b8 100644 --- a/src/Text/Pandoc/Writers/ODT.hs +++ b/src/Text/Pandoc/Writers/ODT.hs @@ -29,19 +29,22 @@ Conversion of 'Pandoc' documents to ODT. -} module Text.Pandoc.Writers.ODT ( writeODT ) where import Data.IORef +import Data.List ( isPrefixOf ) import System.FilePath ( (</>), takeExtension ) import qualified Data.ByteString.Lazy as B import Data.ByteString.Lazy.UTF8 ( fromString ) import Codec.Archive.Zip import System.Time import Paths_pandoc ( getDataFileName ) -import Text.Pandoc.Shared ( WriterOptions(..) ) +import Text.Pandoc.Shared ( WriterOptions(..), getMimeType ) import Text.Pandoc.Definition import Text.Pandoc.Generic import Text.Pandoc.Writers.OpenDocument ( writeOpenDocument ) import System.Directory import Control.Monad (liftM) import Network.URI ( unEscapeString ) +import Text.Pandoc.XML +import Text.Pandoc.Pretty -- | Produce an ODT file from a Pandoc document. writeODT :: Maybe FilePath -- ^ Path specified by --reference-odt @@ -70,8 +73,30 @@ writeODT mbRefOdt opts doc = do (TOD epochtime _) <- getClockTime let contentEntry = toEntry "content.xml" epochtime $ fromString newContents picEntries <- readIORef picEntriesRef - let archive = foldr addEntryToArchive refArchive (contentEntry : picEntries) - return $ fromArchive archive + let archive = foldr addEntryToArchive refArchive $ contentEntry : picEntries + -- construct META-INF/manifest.xml based on archive + let toFileEntry fp = case getMimeType fp of + Nothing -> empty + Just m -> selfClosingTag "manifest:file-entry" + [("manifest:media-type", m) + ,("manifest:full-path", fp) + ] + let files = [ ent | ent <- filesInArchive archive, not ("META-INF" `isPrefixOf` ent) ] + let manifestEntry = toEntry "META-INF/manifest.xml" epochtime + $ fromString $ show + $ text "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + $$ + ( inTags True "manifest:manifest" + [("xmlns:manifest","urn:oasis:names:tc:opendocument:xmlns:manifest:1.0")] + $ ( selfClosingTag "manifest:file-entry" + [("manifest:media-type","application/vnd.oasis.opendocument.text") + ,("manifest:version","1.2") + ,("manifest:full-path","/")] + $$ vcat ( map toFileEntry $ files ) + ) + ) + let archive' = addEntryToArchive manifestEntry archive + return $ fromArchive archive' transformPic :: FilePath -> IORef [Entry] -> Inline -> IO Inline transformPic sourceDir entriesRef (Image lab (src,tit)) = do |