git.iko.soy/typeable/pandoc
on master help sign in
Data files changes.

* Added `embed_data_files` flag. (not yet used) * Shared no longer exports `findDataFile`. * `readDataFile` now returns a strict bytestring. * Shared now exports `readDataFileUTF8` which returns a string like the old `readDataFile`. * Rewrote modules to use new data file functions and to avoid using functions from Paths_pandoc directly.

commit1864bb0994cc70b99ea8207b3a22438c343348c0 authorJohn MacFarlane <fiddlosopher@gmail.com> dateSat 29 Dec 2012, 17:44 (14 years ago) parent32c5a8e
9 files changed+64−67
benchmark/benchmark-pandoc.hs+3−3 pandoc.cabal+7 pandoc.hs+13−9 src/Text/Pandoc/SelfContained.hs+3−13 src/Text/Pandoc/Shared.hs+27−14 src/Text/Pandoc/Templates.hs+2−2 src/Text/Pandoc/Writers/Docx.hs+2−11 src/Text/Pandoc/Writers/EPUB.hs+4−3 src/Text/Pandoc/Writers/ODT.hs+3−12
benchmark/benchmark-pandoc.hs+3−3
@@ -1,5 +1,5 @@
11import Text.Pandoc
2−import Text.Pandoc.Shared (readDataFile, normalize)
2+import Text.Pandoc.Shared (readDataFileUTF8, normalize)
33import Criterion.Main
44import Criterion.Config
55import Text.JSON.Generic
@@ -35,8 +35,8 @@ main :: IO ()
3535main = do
3636 args <- getArgs
3737 (conf,_) <- parseArgs defaultConfig{ cfgSamples = Last $ Just 20 } defaultOptions args
38− inp <- readDataFile (Just ".") "README"
39− inp2 <- readDataFile (Just ".") "tests/testsuite.txt"
38+ inp <- readDataFileUTF8 (Just ".") "README"
39+ inp2 <- readDataFileUTF8 (Just ".") "tests/testsuite.txt"
4040 let opts = def{ readerSmart = True }
4141 let doc = readMarkdown opts $ inp ++ unlines (drop 3 $ lines inp2)
4242 let readerBs = map (readerBench doc) readers
pandoc.cabal+7
@@ -187,6 +187,9 @@ Source-repository head
187187Flag blaze_html_0_5
188188 Description: Use blaze-html 0.5 and blaze-markup 0.5
189189 Default: True
190+Flag embed_data_files
191+ Description: Embed data files in binary for relocatable executable.
192+ Default: False
190193
191194Library
192195 Build-Depends: base >= 4.2 && <5,
@@ -224,6 +227,10 @@ Library
224227 else
225228 build-depends:
226229 blaze-html >= 0.4.3.0 && < 0.5
230+ if flag(embed_data_files)
231+ build-depends: file-embed >= 0.0.4 && < 0.1,
232+ template-haskell >= 2.4 && < 2.9
233+ cpp-options: -DEMBED_DATA_FILES
227234 if impl(ghc >= 7.0.1)
228235 Ghc-Options: -O2 -rtsopts -Wall -fno-warn-unused-do-bind -dno-debug-output
229236 else
pandoc.hs+13−9
@@ -33,7 +33,7 @@ module Main where
3333import Text.Pandoc
3434import Text.Pandoc.PDF (tex2pdf)
3535import Text.Pandoc.Readers.LaTeX (handleIncludes)
36−import Text.Pandoc.Shared ( tabFilter, readDataFile, safeRead,
36+import Text.Pandoc.Shared ( tabFilter, readDataFileUTF8, safeRead,
3737 headerShift, normalize, err, warn )
3838import Text.Pandoc.XML ( toEntities, fromEntities )
3939import Text.Pandoc.SelfContained ( makeSelfContained )
@@ -889,24 +889,27 @@ main = do
889889 E.catch (UTF8.readFile tp')
890890 (\e -> if isDoesNotExistError e
891891 then E.catch
892− (readDataFile datadir $
893− "templates" </> tp')
892+ (readDataFileUTF8 datadir
893+ ("templates" </> tp'))
894894 (\e' -> let _ = (e' :: E.SomeException)
895895 in throwIO e')
896896 else throwIO e)
897897
898898 variables' <- case mathMethod of
899899 LaTeXMathML Nothing -> do
900− s <- readDataFile datadir $ "data" </> "LaTeXMathML.js"
900+ s <- readDataFileUTF8 datadir
901+ ("data" </> "LaTeXMathML.js")
901902 return $ ("mathml-script", s) : variables
902903 MathML Nothing -> do
903− s <- readDataFile datadir $ "data"</>"MathMLinHTML.js"
904+ s <- readDataFileUTF8 datadir
905+ ("data"</>"MathMLinHTML.js")
904906 return $ ("mathml-script", s) : variables
905907 _ -> return variables
906908
907909 variables'' <- if "dzslides" `isPrefixOf` writerName'
908910 then do
909− dztempl <- readDataFile datadir $ "dzslides" </> "template.html"
911+ dztempl <- readDataFileUTF8 datadir
912+ ("dzslides" </> "template.html")
910913 let dzcore = unlines $ dropWhile (not . isPrefixOf "<!-- {{{{ dzslides core")
911914 $ lines dztempl
912915 return $ ("dzslides-core", dzcore) : variables'
@@ -927,15 +930,16 @@ main = do
927930 then do
928931 csl <- CSL.parseCSL =<<
929932 case mbCsl of
930− Nothing -> readDataFile datadir "default.csl"
933+ Nothing -> readDataFileUTF8 datadir
934+ "default.csl"
931935 Just cslfile -> do
932936 exists <- doesFileExist cslfile
933937 if exists
934938 then UTF8.readFile cslfile
935939 else do
936940 csldir <- getAppUserDataDirectory "csl"
937− readDataFile (Just csldir)
938− (replaceExtension cslfile "csl")
941+ readDataFileUTF8 (Just csldir)
942+ (replaceExtension cslfile "csl")
939943 abbrevs <- maybe (return []) CSL.readJsonAbbrevFile cslabbrevs
940944 return $ Just csl { CSL.styleAbbrevs = abbrevs }
941945 else return Nothing
src/Text/Pandoc/SelfContained.hs+3−13
@@ -41,7 +41,7 @@ import System.FilePath (takeExtension, dropExtension, takeDirectory, (</>))
4141import Data.Char (toLower, isAscii, isAlphaNum)
4242import Codec.Compression.GZip as Gzip
4343import qualified Data.ByteString.Lazy as L
44−import Text.Pandoc.Shared (findDataFile, renderTags')
44+import Text.Pandoc.Shared (readDataFile, renderTags')
4545import Text.Pandoc.MIME (getMimeType)
4646import System.Directory (doesFileExist)
4747import Text.Pandoc.UTF8 (toString, fromString)
@@ -55,18 +55,8 @@ getItem userdata f =
5555 ".gz" -> getMimeType $ dropExtension f
5656 x -> getMimeType x
5757 exists <- doesFileExist f
58− if exists
59− then do
60− cont <- B.readFile f
61− return (cont, mime)
62− else do
63− res <- findDataFile userdata f
64− exists' <- doesFileExist res
65− if exists'
66− then do
67− cont <- B.readFile res
68− return (cont, mime)
69− else error $ "Could not find `" ++ f ++ "'"
58+ cont <- if exists then B.readFile f else readDataFile userdata f
59+ return (cont, mime)
7060
7161-- TODO - have this return mime type too - then it can work for google
7262-- chart API, e.g.
src/Text/Pandoc/Shared.hs+27−14
@@ -1,4 +1,4 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
1+{-# LANGUAGE DeriveDataTypeable, CPP #-}
22{-
33Copyright (C) 2006-2010 John MacFarlane <jgm@berkeley.edu>
44
@@ -64,8 +64,8 @@ module Text.Pandoc.Shared (
6464 renderTags',
6565 -- * File handling
6666 inDirectory,
67− findDataFile,
6867 readDataFile,
68+ readDataFileUTF8,
6969 -- * Error handling
7070 err,
7171 warn,
@@ -89,13 +89,18 @@ import System.FilePath ( (</>) )
8989import Data.Generics (Typeable, Data)
9090import qualified Control.Monad.State as S
9191import Control.Monad (msum)
92−import Paths_pandoc (getDataFileName)
9392import Text.Pandoc.Pretty (charWidth)
9493import System.Locale (defaultTimeLocale)
9594import Data.Time
9695import System.IO (stderr)
9796import Text.HTML.TagSoup (renderTagsOptions, RenderOptions(..), Tag(..),
9897 renderOptions)
98+import qualified Data.ByteString as B
99+#ifdef EMBED_DATA_FILES
100+import Data.FileEmbed
101+#else
102+import Paths_pandoc (getDataFileName)
103+#endif
99104
100105--
101106-- List processing
@@ -499,20 +504,28 @@ inDirectory path action = do
499504 setCurrentDirectory oldDir
500505 return result
501506
502−-- | Get file path for data file, either from specified user data directory,
503−-- or, if not found there, from Cabal data directory.
504−findDataFile :: Maybe FilePath -> FilePath -> IO FilePath
505−findDataFile Nothing f = getDataFileName f
506−findDataFile (Just u) f = do
507− ex <- doesFileExist (u </> f)
508− if ex
509− then return (u </> f)
510− else getDataFileName f
507+readDefaultDataFile :: FilePath -> IO B.ByteString
508+readDefaultDataFile fname =
509+#ifdef EMBED_DATA_FILES
510+ TODO
511+#else
512+ getDataFileName fname >>= B.readFile
513+#endif
511514
512515-- | Read file from specified user data directory or, if not found there, from
513516-- Cabal data directory.
514−readDataFile :: Maybe FilePath -> FilePath -> IO String
515−readDataFile userDir fname = findDataFile userDir fname >>= UTF8.readFile
517+readDataFile :: Maybe FilePath -> FilePath -> IO B.ByteString
518+readDataFile Nothing fname = readDefaultDataFile fname
519+readDataFile (Just userDir) fname = do
520+ exists <- doesFileExist (userDir </> fname)
521+ if exists
522+ then B.readFile (userDir </> fname)
523+ else readDefaultDataFile fname
524+
525+-- | Same as 'readDataFile' but returns a String instead of a ByteString.
526+readDataFileUTF8 :: Maybe FilePath -> FilePath -> IO String
527+readDataFileUTF8 userDir fname =
528+ UTF8.toString `fmap` readDataFile userDir fname
516529
517530--
518531-- Error reporting
src/Text/Pandoc/Templates.hs+2−2
@@ -80,7 +80,7 @@ import Text.Blaze (preEscapedString, Html)
8080#endif
8181import Text.Pandoc.UTF8 (fromStringLazy)
8282import Data.ByteString.Lazy (ByteString)
83−import Text.Pandoc.Shared (readDataFile)
83+import Text.Pandoc.Shared (readDataFileUTF8)
8484import qualified Control.Exception.Extensible as E (try, IOException)
8585
8686-- | Get default template for the specified writer.
@@ -98,7 +98,7 @@ getDefaultTemplate user writer = do
9898 "multimarkdown" -> getDefaultTemplate user "markdown"
9999 "markdown_github" -> getDefaultTemplate user "markdown"
100100 _ -> let fname = "templates" </> "default" <.> format
101− in E.try $ readDataFile user fname
101+ in E.try $ readDataFileUTF8 user fname
102102
103103data TemplateState = TemplateState Int [(String,String)]
104104
src/Text/Pandoc/Writers/Docx.hs+2−11
@@ -29,14 +29,12 @@ Conversion of 'Pandoc' documents to docx.
2929-}
3030module Text.Pandoc.Writers.Docx ( writeDocx ) where
3131import Data.List ( intercalate )
32−import System.FilePath ( (</>) )
3332import qualified Data.ByteString.Lazy as B
3433import qualified Data.Map as M
3534import qualified Text.Pandoc.UTF8 as UTF8
3635import System.IO ( stderr )
3736import Codec.Archive.Zip
3837import Data.Time.Clock.POSIX
39−import Paths_pandoc ( getDataFileName )
4038import Text.Pandoc.Definition
4139import Text.Pandoc.Generic
4240import System.Directory
@@ -104,15 +102,8 @@ writeDocx opts doc@(Pandoc (Meta tit auths date) _) = do
104102 refArchive <- liftM toArchive $
105103 case writerReferenceDocx opts of
106104 Just f -> B.readFile f
107− Nothing -> do
108− let defaultDocx = getDataFileName "reference.docx" >>= B.readFile
109− case datadir of
110− Nothing -> defaultDocx
111− Just d -> do
112− exists <- doesFileExist (d </> "reference.docx")
113− if exists
114− then B.readFile (d </> "reference.docx")
115− else defaultDocx
105+ Nothing -> (B.fromChunks . (:[])) `fmap`
106+ readDataFile datadir "reference.docx"
116107
117108 (newContents, st) <- runStateT (writeOpenXML opts{writerWrapText = False} doc)
118109 defaultWriterState
src/Text/Pandoc/Writers/EPUB.hs+4−3
@@ -30,13 +30,13 @@ Conversion of 'Pandoc' documents to EPUB.
3030module Text.Pandoc.Writers.EPUB ( writeEPUB2, writeEPUB3 ) where
3131import Data.IORef
3232import Data.Maybe ( fromMaybe, isNothing )
33−import Data.List ( isPrefixOf, isInfixOf, intercalate )
33+import Data.List ( isInfixOf, intercalate )
3434import System.Environment ( getEnv )
3535import Text.Printf (printf)
3636import System.FilePath ( (</>), takeBaseName, takeExtension, takeFileName )
3737import qualified Data.ByteString.Lazy as B
3838import qualified Data.ByteString.Lazy.Char8 as B8
39−import Text.Pandoc.UTF8 ( fromStringLazy )
39+import Text.Pandoc.UTF8 ( fromStringLazy, toString )
4040import Codec.Archive.Zip
4141import Data.Time.Clock.POSIX
4242import Data.Time
@@ -321,7 +321,8 @@ writeEPUB version opts doc@(Pandoc meta _) = do
321321 -- stylesheet
322322 stylesheet <- case writerEpubStylesheet opts of
323323 Just s -> return s
324− Nothing -> readDataFile (writerUserDataDir opts) "epub.css"
324+ Nothing -> toString `fmap`
325+ readDataFile (writerUserDataDir opts) "epub.css"
325326 let stylesheetEntry = mkEntry "stylesheet.css" $ fromStringLazy stylesheet
326327
327328 -- construct archive
src/Text/Pandoc/Writers/ODT.hs+3−12
@@ -35,15 +35,13 @@ import qualified Data.ByteString.Lazy as B
3535import Text.Pandoc.UTF8 ( fromStringLazy )
3636import Codec.Archive.Zip
3737import Data.Time.Clock.POSIX
38−import Paths_pandoc ( getDataFileName )
3938import Text.Pandoc.Options ( WriterOptions(..) )
40−import Text.Pandoc.Shared ( stringify )
39+import Text.Pandoc.Shared ( stringify, readDataFile )
4140import Text.Pandoc.ImageSize ( readImageSize, sizeInPoints )
4241import Text.Pandoc.MIME ( getMimeType )
4342import Text.Pandoc.Definition
4443import Text.Pandoc.Generic
4544import Text.Pandoc.Writers.OpenDocument ( writeOpenDocument )
46−import System.Directory
4745import Control.Monad (liftM)
4846import Network.URI ( unEscapeString )
4947import Text.Pandoc.XML
@@ -59,15 +57,8 @@ writeODT opts doc@(Pandoc (Meta title _ _) _) = do
5957 refArchive <- liftM toArchive $
6058 case writerReferenceODT opts of
6159 Just f -> B.readFile f
62− Nothing -> do
63− let defaultODT = getDataFileName "reference.odt" >>= B.readFile
64− case datadir of
65− Nothing -> defaultODT
66− Just d -> do
67− exists <- doesFileExist (d </> "reference.odt")
68− if exists
69− then B.readFile (d </> "reference.odt")
70− else defaultODT
60+ Nothing -> (B.fromChunks . (:[])) `fmap`
61+ readDataFile datadir "reference.odt"
7162 -- handle pictures
7263 picEntriesRef <- newIORef ([] :: [Entry])
7364 let sourceDir = writerSourceDirectory opts