git.iko.soy/typeable/pandoc
on master help sign in
Let reference.docx/odt behave as if they are virtual data files.

Now they are constructed on the fly from their components, but we now allow them to be printed with `--print-default-data-file` and to override the defaults if placed in the user data directory. Shared now exports getDefaultReferenceDocx and getDefaultReferenceODT (API change). These functions have been removed from the Docx and ODT writers. Shared.readDataFile has been modified so that requests to read a reference.odt or reference.docx will use these functions to generate the files.

commitde184a80ec878498c808d71faba7f373458d5288 authorJohn MacFarlane <jgm@berkeley.edu> dateSun 28 Jun 2015, 22:30 (11 years ago) parent7bbb007
3 files changed+74−44
src/Text/Pandoc/Shared.hs+72−1 src/Text/Pandoc/Writers/Docx.hs−24 src/Text/Pandoc/Writers/ODT.hs+2−19
src/Text/Pandoc/Shared.hs+72−1
@@ -76,6 +76,8 @@ module Text.Pandoc.Shared (
7676 renderTags',
7777 -- * File handling
7878 inDirectory,
79+ getDefaultReferenceDocx,
80+ getDefaultReferenceODT,
7981 readDataFile,
8082 readDataFileUTF8,
8183 fetchItem,
@@ -119,6 +121,7 @@ import Control.Monad (msum, unless, MonadPlus(..))
119121import Text.Pandoc.Pretty (charWidth)
120122import Text.Pandoc.Compat.Locale (defaultTimeLocale)
121123import Data.Time
124+import Data.Time.Clock.POSIX
122125import System.IO (stderr)
123126import System.IO.Temp
124127import Text.HTML.TagSoup (renderTagsOptions, RenderOptions(..), Tag(..),
@@ -129,7 +132,8 @@ import Text.Pandoc.Compat.Monoid
129132import Data.ByteString.Base64 (decodeLenient)
130133import Data.Sequence (ViewR(..), ViewL(..), viewl, viewr)
131134import qualified Data.Text as T (toUpper, pack, unpack)
132−import Data.ByteString.Lazy (toChunks)
135+import Data.ByteString.Lazy (toChunks, fromChunks)
136+import qualified Data.ByteString.Lazy as BL
133137
134138#ifdef EMBED_DATA_FILES
135139import Text.Pandoc.Data (dataFiles)
@@ -145,6 +149,7 @@ import Network.HTTP.Client.TLS (tlsManagerSettings)
145149import System.Environment (getEnv)
146150import Network.HTTP.Types.Header ( hContentType)
147151import Network (withSocketsDo)
152+import Codec.Archive.Zip
148153#else
149154import Network.URI (parseURI)
150155import Network.HTTP (findHeader, rspBody,
@@ -742,7 +747,73 @@ inDirectory path action = E.bracket
742747 setCurrentDirectory
743748 (const $ setCurrentDirectory path >> action)
744749
750+getDefaultReferenceDocx :: Maybe FilePath -> IO Archive
751+getDefaultReferenceDocx datadir = do
752+ let paths = ["[Content_Types].xml",
753+ "_rels/.rels",
754+ "docProps/app.xml",
755+ "docProps/core.xml",
756+ "word/document.xml",
757+ "word/fontTable.xml",
758+ "word/footnotes.xml",
759+ "word/numbering.xml",
760+ "word/settings.xml",
761+ "word/webSettings.xml",
762+ "word/styles.xml",
763+ "word/_rels/document.xml.rels",
764+ "word/_rels/footnotes.xml.rels",
765+ "word/theme/theme1.xml"]
766+ let toLazy = fromChunks . (:[])
767+ let pathToEntry path = do epochtime <- (floor . utcTimeToPOSIXSeconds) <$>
768+ getCurrentTime
769+ contents <- toLazy <$> readDataFile datadir
770+ ("docx/" ++ path)
771+ return $ toEntry path epochtime contents
772+ mbArchive <- case datadir of
773+ Nothing -> return Nothing
774+ Just d -> do
775+ exists <- doesFileExist (d </> "reference.docx")
776+ if exists
777+ then return (Just (d </> "reference.docx"))
778+ else return Nothing
779+ case mbArchive of
780+ Just arch -> toArchive <$> BL.readFile arch
781+ Nothing -> foldr addEntryToArchive emptyArchive <$>
782+ mapM pathToEntry paths
783+
784+getDefaultReferenceODT :: Maybe FilePath -> IO Archive
785+getDefaultReferenceODT datadir = do
786+ let paths = ["mimetype",
787+ "manifest.rdf",
788+ "styles.xml",
789+ "content.xml",
790+ "meta.xml",
791+ "settings.xml",
792+ "Configurations2/accelerator/current.xml",
793+ "Thumbnails/thumbnail.png",
794+ "META-INF/manifest.xml"]
795+ let pathToEntry path = do epochtime <- floor `fmap` getPOSIXTime
796+ contents <- (fromChunks . (:[])) `fmap`
797+ readDataFile datadir ("odt/" ++ path)
798+ return $ toEntry path epochtime contents
799+ mbArchive <- case datadir of
800+ Nothing -> return Nothing
801+ Just d -> do
802+ exists <- doesFileExist (d </> "reference.odt")
803+ if exists
804+ then return (Just (d </> "reference.odt"))
805+ else return Nothing
806+ case mbArchive of
807+ Just arch -> toArchive <$> BL.readFile arch
808+ Nothing -> foldr addEntryToArchive emptyArchive <$>
809+ mapM pathToEntry paths
810+
811+
745812readDefaultDataFile :: FilePath -> IO BS.ByteString
813+readDefaultDataFile "reference.docx" =
814+ (BS.concat . toChunks . fromArchive) <$> getDefaultReferenceDocx Nothing
815+readDefaultDataFile "reference.odt" =
816+ (BS.concat . toChunks . fromArchive) <$> getDefaultReferenceODT Nothing
746817readDefaultDataFile fname =
747818#ifdef EMBED_DATA_FILES
748819 case lookup (makeCanonical fname) dataFiles of
src/Text/Pandoc/Writers/Docx.hs−24
@@ -1220,27 +1220,3 @@ fitToPage (x, y) pageWidth
12201220 ((fromIntegral pageWidth) / ((fromIntegral :: Integer -> Double) x)) * (fromIntegral y))
12211221 | otherwise = (x, y)
12221222
1223−getDefaultReferenceDocx :: Maybe FilePath -> IO Archive
1224−getDefaultReferenceDocx datadir = do
1225− let paths = ["[Content_Types].xml",
1226− "_rels/.rels",
1227− "docProps/app.xml",
1228− "docProps/core.xml",
1229− "word/document.xml",
1230− "word/fontTable.xml",
1231− "word/footnotes.xml",
1232− "word/numbering.xml",
1233− "word/settings.xml",
1234− "word/webSettings.xml",
1235− "word/styles.xml",
1236− "word/_rels/document.xml.rels",
1237− "word/_rels/footnotes.xml.rels",
1238− "word/theme/theme1.xml"]
1239− let pathToEntry path = do epochtime <- (floor . utcTimeToPOSIXSeconds) <$>
1240− getCurrentTime
1241− contents <- toLazy <$> readDataFile datadir
1242− ("docx/" ++ path)
1243− return $ toEntry path epochtime contents
1244− entries <- mapM pathToEntry paths
1245− let archive = foldr addEntryToArchive emptyArchive entries
1246− return archive
src/Text/Pandoc/Writers/ODT.hs+2−19
@@ -39,7 +39,8 @@ import Text.Pandoc.UTF8 ( fromStringLazy )
3939import Codec.Archive.Zip
4040import Control.Applicative ((<$>))
4141import Text.Pandoc.Options ( WriterOptions(..) )
42−import Text.Pandoc.Shared ( stringify, readDataFile, fetchItem', warn )
42+import Text.Pandoc.Shared ( stringify, readDataFile, fetchItem', warn,
43+ getDefaultReferenceODT )
4344import Text.Pandoc.ImageSize ( imageSize, sizeInPoints )
4445import Text.Pandoc.MIME ( getMimeType, extensionFromMimeType )
4546import Text.Pandoc.Definition
@@ -177,21 +178,3 @@ transformPicMath _ entriesRef (Math t math) = do
177178 , ("xlink:actuate", "onLoad")]
178179
179180transformPicMath _ _ x = return x
180−
181−getDefaultReferenceODT :: Maybe FilePath -> IO Archive
182−getDefaultReferenceODT datadir = do
183− let paths = ["mimetype",
184− "manifest.rdf",
185− "styles.xml",
186− "content.xml",
187− "meta.xml",
188− "settings.xml",
189− "Configurations2/accelerator/current.xml",
190− "Thumbnails/thumbnail.png",
191− "META-INF/manifest.xml"]
192− let pathToEntry path = do epochtime <- floor `fmap` getPOSIXTime
193− contents <- (B.fromChunks . (:[])) `fmap`
194− readDataFile datadir ("odt/" ++ path)
195− return $ toEntry path epochtime contents
196− entries <- mapM pathToEntry paths
197− return $ foldr addEntryToArchive emptyArchive entries