git.iko.soy/typeable/pandoc
on master help sign in
Implement runTest functions.
e24d5a5Jesse Rosenthal
pandoc.cabal+1−1
@@ -290,7 +290,7 @@ Library
290 old-time,
290 old-time,
291 deepseq >= 1.3 && < 1.5,
291 deepseq >= 1.3 && < 1.5,
292 JuicyPixels >= 3.1.6.1 && < 3.3,
292 JuicyPixels >= 3.1.6.1 && < 3.3,
293− filemanip >= 0.3 && < 0.4,
293+ Glob >= 0.7 && < 0.8,
294 cmark >= 0.5 && < 0.6,
294 cmark >= 0.5 && < 0.6,
295 doctemplates >= 0.1 && < 0.2,
295 doctemplates >= 0.1 && < 0.2,
296 free >= 4
296 free >= 4
src/Text/Pandoc/Free.hs+159−58
@@ -33,6 +33,7 @@ Pure implementations of the IO monads used in Pandoc's readers and writers.
33module Text.Pandoc.Free ( PandocActionF(..)
33module Text.Pandoc.Free ( PandocActionF(..)
34 , PandocAction
34 , PandocAction
35 , runIO
35 , runIO
36+ , runTest
36 , liftF
37 , liftF
37 --
38 --
38 , lookupEnv
39 , lookupEnv
@@ -41,7 +42,7 @@ module Text.Pandoc.Free ( PandocActionF(..)
41 , getDefaultReferenceDocx
42 , getDefaultReferenceDocx
42 , getDefaultReferenceODT
43 , getDefaultReferenceODT
43 , newStdGen
44 , newStdGen
44− , newUnique
45+ , newUniqueHash
45 , newUUID
46 , newUUID
46 , readFileStrict
47 , readFileStrict
47 , readFileLazy
48 , readFileLazy
@@ -51,18 +52,15 @@ module Text.Pandoc.Free ( PandocActionF(..)
51 , fetchItem'
52 , fetchItem'
52 , warn
53 , warn
53 , fail
54 , fail
54− , newIORef
55+ , glob
55− , modifyIORef
56− , readIORef
57− , namesMatching
58 ) where
56 ) where
59
57
60import Prelude hiding (readFile, fail)
58import Prelude hiding (readFile, fail)
61import qualified Control.Monad as M (fail)
59import qualified Control.Monad as M (fail)
62−import System.Random (StdGen)
60+import System.Random (StdGen, next)
63import qualified System.Random as IO (newStdGen)
61import qualified System.Random as IO (newStdGen)
64−import Codec.Archive.Zip (Archive)
62+import Codec.Archive.Zip (Archive, fromArchive)
65−import Data.Unique (Unique)
63+import Data.Unique (Unique, hashUnique, newUnique)
66import qualified Data.Unique as IO (newUnique)
64import qualified Data.Unique as IO (newUnique)
67import qualified Text.Pandoc.Shared as IO ( fetchItem
65import qualified Text.Pandoc.Shared as IO ( fetchItem
68 , fetchItem'
66 , fetchItem'
@@ -70,32 +68,35 @@ import qualified Text.Pandoc.Shared as IO ( fetchItem
70 , getDefaultReferenceODT
68 , getDefaultReferenceODT
71 , warn
69 , warn
72 , readDataFile)
70 , readDataFile)
73−import Text.Pandoc.MediaBag (MediaBag)
71+import Text.Pandoc.MediaBag (MediaBag, lookupMedia)
74−import Data.Time.Clock.POSIX (POSIXTime)
72+import Data.Time.Clock.POSIX (POSIXTime, utcTimeToPOSIXSeconds)
75import qualified Data.Time.Clock.POSIX as IO (getPOSIXTime)
73import qualified Data.Time.Clock.POSIX as IO (getPOSIXTime)
76import Text.Pandoc.Compat.Time (UTCTime)
74import Text.Pandoc.Compat.Time (UTCTime)
77import qualified Text.Pandoc.Compat.Time as IO (getCurrentTime)
75import qualified Text.Pandoc.Compat.Time as IO (getCurrentTime)
78−import Text.Pandoc.MIME (MimeType)
76+import Text.Pandoc.MIME (MimeType, getMimeType)
79import qualified Data.ByteString as B
77import qualified Data.ByteString as B
80import qualified Data.ByteString.Lazy as BL
78import qualified Data.ByteString.Lazy as BL
81import Control.Monad.Free
79import Control.Monad.Free
82import qualified Control.Exception as E
80import qualified Control.Exception as E
83import qualified System.Environment as IO (lookupEnv)
81import qualified System.Environment as IO (lookupEnv)
84−import Data.IORef (IORef)
85−import qualified Data.IORef as IO (newIORef, modifyIORef, readIORef)
86−import Text.Pandoc.UUID (UUID)
82+import Text.Pandoc.UUID
87import qualified Text.Pandoc.UUID as IO (getRandomUUID)
83import qualified Text.Pandoc.UUID as IO (getRandomUUID)
88−import qualified Text.Pandoc.UTF8 as UTF8 (readFile)
84+import qualified Text.Pandoc.UTF8 as UTF8 (readFile, toString)
85+import System.FilePath.Glob (match, compile)
86+import System.FilePath ((</>))
89−import qualified System.FilePath.Glob as IO (namesMatching)
87+import qualified System.FilePath.Glob as IO (glob)
90−
88+import Control.Monad.State hiding (fail)
89+import Control.Monad.Reader hiding (fail)
90+import Data.Word (Word8)
91+
91−data PandocActionF ref nxt =
92+data PandocActionF nxt =
92 LookupEnv String (Maybe String -> nxt)
93 LookupEnv String (Maybe String -> nxt)
93 | GetCurrentTime (UTCTime -> nxt)
94 | GetCurrentTime (UTCTime -> nxt)
94 | GetPOSIXTime (POSIXTime -> nxt)
95 | GetPOSIXTime (POSIXTime -> nxt)
95 | GetDefaultReferenceDocx (Maybe FilePath) (Archive -> nxt)
96 | GetDefaultReferenceDocx (Maybe FilePath) (Archive -> nxt)
96 | GetDefaultReferenceODT (Maybe FilePath) (Archive -> nxt)
97 | GetDefaultReferenceODT (Maybe FilePath) (Archive -> nxt)
97 | NewStdGen (StdGen -> nxt)
98 | NewStdGen (StdGen -> nxt)
98− | NewUnique (Unique -> nxt)
99+ | NewUniqueHash (Int -> nxt)
99 | NewUUID (UUID -> nxt)
100 | NewUUID (UUID -> nxt)
100 | ReadFileStrict FilePath (B.ByteString -> nxt)
101 | ReadFileStrict FilePath (B.ByteString -> nxt)
101 | ReadFileLazy FilePath (BL.ByteString -> nxt)
102 | ReadFileLazy FilePath (BL.ByteString -> nxt)
@@ -105,83 +106,71 @@ data PandocActionF ref nxt =
105 (Either E.SomeException (B.ByteString, Maybe MimeType) -> nxt)
106 (Either E.SomeException (B.ByteString, Maybe MimeType) -> nxt)
106 | FetchItem' MediaBag (Maybe String) (String)
107 | FetchItem' MediaBag (Maybe String) (String)
107 (Either E.SomeException (B.ByteString, Maybe MimeType) -> nxt)
108 (Either E.SomeException (B.ByteString, Maybe MimeType) -> nxt)
108− | NewIORef ref (IORef ref -> nxt)
109− | ModifyIORef (IORef ref) (ref -> ref) nxt
110− | ReadIORef (IORef ref) (ref -> nxt)
111− | NamesMatching String ([FilePath] -> nxt)
109+ | Glob String ([FilePath] -> nxt)
112 | Warn String nxt
110 | Warn String nxt
113 | Fail String
111 | Fail String
114 deriving Functor
112 deriving Functor
115
113
116−type PandocAction a = Free (PandocActionF a)
114+type PandocAction = Free PandocActionF
117
115
118−lookupEnv :: String -> PandocAction a (Maybe String)
116+lookupEnv :: String -> PandocAction (Maybe String)
119lookupEnv s = liftF $ LookupEnv s id
117lookupEnv s = liftF $ LookupEnv s id
120
118
121−getCurrentTime :: PandocAction a UTCTime
119+getCurrentTime :: PandocAction UTCTime
122getCurrentTime = liftF $ GetCurrentTime id
120getCurrentTime = liftF $ GetCurrentTime id
123
121
124−getPOSIXTime :: PandocAction a POSIXTime
122+getPOSIXTime :: PandocAction POSIXTime
125getPOSIXTime = liftF $ GetPOSIXTime id
123getPOSIXTime = liftF $ GetPOSIXTime id
126
124
127−getDefaultReferenceDocx :: Maybe FilePath -> PandocAction a Archive
125+getDefaultReferenceDocx :: Maybe FilePath -> PandocAction Archive
128getDefaultReferenceDocx fp = liftF $ GetDefaultReferenceDocx fp id
126getDefaultReferenceDocx fp = liftF $ GetDefaultReferenceDocx fp id
129
127
130−getDefaultReferenceODT :: Maybe FilePath -> PandocAction a Archive
128+getDefaultReferenceODT :: Maybe FilePath -> PandocAction Archive
131getDefaultReferenceODT fp = liftF $ GetDefaultReferenceODT fp id
129getDefaultReferenceODT fp = liftF $ GetDefaultReferenceODT fp id
132
130
133−newStdGen :: PandocAction a StdGen
131+newStdGen :: PandocAction StdGen
134newStdGen = liftF $ NewStdGen id
132newStdGen = liftF $ NewStdGen id
135
133
136−newUnique :: PandocAction a Unique
134+newUniqueHash :: PandocAction Int
137−newUnique = liftF $ NewUnique id
135+newUniqueHash = liftF $ NewUniqueHash id
138
136
139−newUUID :: PandocAction a UUID
137+newUUID :: PandocAction UUID
140newUUID = liftF $ NewUUID id
138newUUID = liftF $ NewUUID id
141
139
142−readFileStrict :: FilePath -> PandocAction a B.ByteString
140+readFileStrict :: FilePath -> PandocAction B.ByteString
143readFileStrict fp = liftF $ ReadFileStrict fp id
141readFileStrict fp = liftF $ ReadFileStrict fp id
144
142
145−readFileLazy :: FilePath -> PandocAction a BL.ByteString
143+readFileLazy :: FilePath -> PandocAction BL.ByteString
146readFileLazy fp = liftF $ ReadFileLazy fp id
144readFileLazy fp = liftF $ ReadFileLazy fp id
147
145
148−readFileUTF8 :: FilePath -> PandocAction a String
146+readFileUTF8 :: FilePath -> PandocAction String
149readFileUTF8 fp = liftF $ ReadFileUTF8 fp id
147readFileUTF8 fp = liftF $ ReadFileUTF8 fp id
150
148
151−readDataFile :: Maybe FilePath -> FilePath -> PandocAction a B.ByteString
149+readDataFile :: Maybe FilePath -> FilePath -> PandocAction B.ByteString
152readDataFile mfp fp = liftF $ ReadDataFile mfp fp id
150readDataFile mfp fp = liftF $ ReadDataFile mfp fp id
153
151
154fetchItem :: Maybe String ->
152fetchItem :: Maybe String ->
155 String ->
153 String ->
156− PandocAction a (Either E.SomeException (B.ByteString, Maybe MimeType))
154+ PandocAction (Either E.SomeException (B.ByteString, Maybe MimeType))
157fetchItem ms s = liftF $ FetchItem ms s id
155fetchItem ms s = liftF $ FetchItem ms s id
158
156
159
157
160fetchItem' :: MediaBag ->
158fetchItem' :: MediaBag ->
161 Maybe String ->
159 Maybe String ->
162 String ->
160 String ->
163− PandocAction a (Either E.SomeException (B.ByteString, Maybe MimeType))
161+ PandocAction (Either E.SomeException (B.ByteString, Maybe MimeType))
164fetchItem' mb ms s = liftF $ FetchItem' mb ms s id
162fetchItem' mb ms s = liftF $ FetchItem' mb ms s id
165
163
166−warn :: String -> PandocAction a ()
164+warn :: String -> PandocAction ()
167warn s = liftF $ Warn s ()
165warn s = liftF $ Warn s ()
168
166
169−fail :: String -> PandocAction a b
167+fail :: String -> PandocAction b
170fail s = liftF $ Fail s
168fail s = liftF $ Fail s
171
169
172−newIORef :: a -> PandocAction a (IORef a)
173−newIORef v = liftF $ NewIORef v id
174−
175−modifyIORef :: (IORef a) -> (a -> a) -> PandocAction a ()
176−modifyIORef ref f = liftF $ ModifyIORef ref f ()
177−
178−readIORef :: (IORef a) -> PandocAction a a
179−readIORef ref = liftF $ ReadIORef ref id
180−
181−namesMatching :: String -> PandocAction a [FilePath]
170+glob :: String -> PandocAction [FilePath]
182−namesMatching s = liftF $ NamesMatching s id
171+glob s = liftF $ Glob s id
183
172
184−runIO :: PandocAction ref nxt -> IO nxt
173+runIO :: PandocAction nxt -> IO nxt
185runIO (Free (LookupEnv s f)) = IO.lookupEnv s >>= runIO . f
174runIO (Free (LookupEnv s f)) = IO.lookupEnv s >>= runIO . f
186runIO (Free (GetCurrentTime f)) = IO.getCurrentTime >>= runIO . f
175runIO (Free (GetCurrentTime f)) = IO.getCurrentTime >>= runIO . f
187runIO (Free (GetPOSIXTime f)) = IO.getPOSIXTime >>= runIO . f
176runIO (Free (GetPOSIXTime f)) = IO.getPOSIXTime >>= runIO . f
@@ -190,7 +179,7 @@ runIO (Free (GetDefaultReferenceDocx mfp f)) =
190runIO (Free (GetDefaultReferenceODT mfp f)) =
179runIO (Free (GetDefaultReferenceODT mfp f)) =
191 IO.getDefaultReferenceODT mfp >>= runIO . f
180 IO.getDefaultReferenceODT mfp >>= runIO . f
192runIO (Free (NewStdGen f)) = IO.newStdGen >>= runIO . f
181runIO (Free (NewStdGen f)) = IO.newStdGen >>= runIO . f
193−runIO (Free (NewUnique f)) = IO.newUnique >>= runIO . f
182+runIO (Free (NewUniqueHash f)) = hashUnique <$> IO.newUnique >>= runIO . f
194runIO (Free (NewUUID f)) = IO.getRandomUUID >>= runIO . f
183runIO (Free (NewUUID f)) = IO.getRandomUUID >>= runIO . f
195runIO (Free (ReadFileStrict fp f)) = B.readFile fp >>= runIO . f
184runIO (Free (ReadFileStrict fp f)) = B.readFile fp >>= runIO . f
196runIO (Free (ReadFileLazy fp f)) = BL.readFile fp >>= runIO . f
185runIO (Free (ReadFileLazy fp f)) = BL.readFile fp >>= runIO . f
@@ -202,8 +191,120 @@ runIO (Free (FetchItem sourceUrl nm f)) =
202runIO (Free (FetchItem' media sourceUrl nm f)) =
191runIO (Free (FetchItem' media sourceUrl nm f)) =
203 IO.fetchItem' media sourceUrl nm >>= runIO . f
192 IO.fetchItem' media sourceUrl nm >>= runIO . f
204runIO (Free (Warn s nxt)) = IO.warn s >> runIO nxt
193runIO (Free (Warn s nxt)) = IO.warn s >> runIO nxt
205−runIO (Free (NewIORef v f)) = IO.newIORef v >>= runIO . f
194+runIO (Free (Glob s f)) = IO.glob s >>= runIO . f
206−runIO (Free (ModifyIORef ref f nxt)) = IO.modifyIORef ref f >> runIO nxt
207−runIO (Free (ReadIORef ref f)) = IO.readIORef ref >>= runIO . f
208−runIO (Free (NamesMatching s f)) = IO.namesMatching s >>= runIO . f
209runIO (Pure r) = return r
195runIO (Pure r) = return r
196+
197+data TestState = TestState { stStdGen :: StdGen
198+ , stWord8Store :: [Word8] -- should be
199+ -- inifinite,
200+ -- i.e. [1..]
201+ , stWarnings :: [String]
202+ , stUniqStore :: [Int] -- should be
203+ -- inifinite and
204+ -- contain every
205+ -- element at most
206+ -- once, e.g. [1..]
207+ }
208+
209+data TestEnv = TestEnv { envEnv :: [(String, String)]
210+ , envTime :: UTCTime
211+ , envReferenceDocx :: Archive
212+ , envReferenceODT :: Archive
213+ , envFiles :: [(FilePath, B.ByteString)]
214+ , envUserDataDir :: [(FilePath, B.ByteString)]
215+ , envCabalDataDir :: [(FilePath, B.ByteString)]
216+ , envFontFiles :: [FilePath]
217+ }
218+
219+data TestException = TestException
220+ deriving (Show)
221+
222+instance E.Exception TestException
223+
224+type Testing = ReaderT TestEnv (State TestState)
225+
226+runTest :: PandocAction nxt -> Testing nxt
227+runTest (Free (LookupEnv s f)) = do
228+ env <- asks envEnv
229+ return (lookup s env) >>= runTest . f
230+runTest (Free (GetCurrentTime f)) =
231+ asks envTime >>= runTest . f
232+runTest (Free (GetPOSIXTime f)) =
233+ (utcTimeToPOSIXSeconds <$> asks envTime) >>= runTest . f
234+runTest (Free (GetDefaultReferenceDocx _ f)) =
235+ asks envReferenceDocx >>= runTest . f
236+runTest (Free (GetDefaultReferenceODT _ f)) =
237+ asks envReferenceODT >>= runTest . f
238+runTest (Free (NewStdGen f)) = do
239+ g <- gets stStdGen
240+ let (_, nxtGen) = next g
241+ modify $ \st -> st { stStdGen = nxtGen }
242+ return g >>= runTest . f
243+runTest (Free (NewUniqueHash f)) = do
244+ uniqs <- gets stUniqStore
245+ case uniqs of
246+ u : us -> do
247+ modify $ \st -> st { stUniqStore = us }
248+ return u >>= runTest . f
249+ _ -> M.fail "uniq store ran out of elements"
250+runTest (Free (NewUUID f)) = do
251+ word8s <- gets stWord8Store
252+ case word8s of
253+ -- note we use f' because f is a param of the function
254+ a:b:c:d:e:f':g:h:i:j:k:l:m:n:o:p:remaining -> do
255+ modify $ \st -> st { stWord8Store = remaining }
256+ return (UUID a b c d e f' g h i j k l m n o p) >>= runTest . f
257+ _ -> M.fail "word8 supply was not infinite"
258+runTest (Free (ReadFileStrict fp f)) = do
259+ fps <- asks envFiles
260+ case lookup fp fps of
261+ Just bs -> return bs >>= runTest . f
262+ Nothing -> error "openFile: does not exist"
263+runTest (Free (ReadFileLazy fp f)) = do
264+ fps <- asks envFiles
265+ case lookup fp fps of
266+ Just bs -> return (BL.fromStrict bs) >>= runTest . f
267+ Nothing -> error "openFile: does not exist"
268+runTest (Free (ReadFileUTF8 fp f)) = do
269+ fps <- asks envFiles
270+ case lookup fp fps of
271+ Just bs -> return (UTF8.toString bs) >>= runTest . f
272+ Nothing -> error "openFile: does not exist"
273+-- A few different cases of readDataFile to reimplement, for when
274+-- there is no filepath and it falls through to readDefaultDataFile
275+runTest (Free (ReadDataFile Nothing "reference.docx" f)) = do
276+ (B.concat . BL.toChunks . fromArchive) <$>
277+ (runTest $ getDefaultReferenceDocx Nothing) >>=
278+ runTest . f
279+runTest (Free (ReadDataFile Nothing "reference.odt" f)) = do
280+ (B.concat . BL.toChunks . fromArchive) <$>
281+ (runTest $ getDefaultReferenceODT Nothing) >>=
282+ runTest . f
283+runTest (Free (ReadDataFile Nothing fname f)) = do
284+ let fname' = if fname == "MANUAL.txt" then fname else "data" </> fname
285+ runTest (readFileStrict fname') >>= runTest . f
286+runTest (Free (ReadDataFile (Just userDir) fname f)) = do
287+ userDirFiles <- asks envUserDataDir
288+ case lookup (userDir </> fname) userDirFiles of
289+ Just bs -> return bs >>= runTest . f
290+ Nothing -> runTest (readDataFile Nothing fname) >>= runTest . f
291+runTest (Free (Fail s)) = M.fail s
292+runTest (Free (FetchItem _ fp f)) = do
293+ fps <- asks envFiles
294+ case lookup fp fps of
295+ Just bs -> return (Right (bs, getMimeType fp)) >>= runTest . f
296+ Nothing -> return (Left $ E.toException TestException) >>= runTest . f
297+runTest (Free (FetchItem' media sourceUrl nm f)) = do
298+ case lookupMedia nm media of
299+ Nothing -> runTest (fetchItem sourceUrl nm) >>= runTest . f
300+ Just (mime, bs) -> return (Right (B.concat $ BL.toChunks bs, Just mime)) >>= runTest . f
301+runTest (Free (Warn s nxt)) = do
302+ modify $ \st -> st { stWarnings = s : stWarnings st }
303+ runTest nxt
304+runTest (Free (Glob s f)) = do
305+ fontFiles <- asks envFontFiles
306+ return (filter (match (compile s)) fontFiles) >>= runTest . f
307+runTest (Pure r) = return r
308+
309+
310+
src/Text/Pandoc/UUID.hs+1−1
@@ -29,7 +29,7 @@ UUID generation using Version 4 (random method) described
29in RFC4122. See http://tools.ietf.org/html/rfc4122
29in RFC4122. See http://tools.ietf.org/html/rfc4122
30-}
30-}
31
31
32−module Text.Pandoc.UUID ( UUID, getRandomUUID ) where
32+module Text.Pandoc.UUID ( UUID(..), getRandomUUID ) where
33
33
34import Text.Printf ( printf )
34import Text.Printf ( printf )
35import System.Random ( randomIO )
35import System.Random ( randomIO )
src/Text/Pandoc/Writers/Docx.hs+8−11
@@ -55,7 +55,6 @@ import Text.Pandoc.Readers.Docx.Util (elemName)
55import Control.Monad.Reader
55import Control.Monad.Reader
56import Control.Monad.State
56import Control.Monad.State
57import Skylighting
57import Skylighting
58−import Data.Unique (hashUnique, newUnique)
59import System.Random (randomR)
58import System.Random (randomR)
60import Text.Printf (printf)
59import Text.Printf (printf)
61import qualified Control.Exception as E
60import qualified Control.Exception as E
@@ -69,8 +68,6 @@ import Data.Char (ord, isSpace, toLower)
69import Text.Pandoc.Free (PandocAction, runIO)
68import Text.Pandoc.Free (PandocAction, runIO)
70import qualified Text.Pandoc.Free as P
69import qualified Text.Pandoc.Free as P
71
70
72−type DocxAction = PandocAction ()
73−
74data ListMarker = NoMarker
71data ListMarker = NoMarker
75 | BulletMarker
72 | BulletMarker
76 | NumberMarker ListNumberStyle ListNumberDelim Int
73 | NumberMarker ListNumberStyle ListNumberDelim Int
@@ -149,7 +146,7 @@ defaultWriterState = WriterState{
149 , stDynamicTextProps = []
146 , stDynamicTextProps = []
150 }
147 }
151
148
152−type WS = ReaderT WriterEnv (StateT WriterState (DocxAction))
149+type WS = ReaderT WriterEnv (StateT WriterState (PandocAction))
153
150
154mknode :: Node t => String -> [(String,String)] -> t -> Element
151mknode :: Node t => String -> [(String,String)] -> t -> Element
155mknode s attrs =
152mknode s attrs =
@@ -227,7 +224,7 @@ writeDocx opts doc = runIO $ writeDocxPure opts doc
227-- | Produce an Docx file from a Pandoc document.
224-- | Produce an Docx file from a Pandoc document.
228writeDocxPure :: WriterOptions -- ^ Writer options
225writeDocxPure :: WriterOptions -- ^ Writer options
229 -> Pandoc -- ^ Document to convert
226 -> Pandoc -- ^ Document to convert
230− -> DocxAction BL.ByteString
227+ -> PandocAction BL.ByteString
231writeDocxPure opts doc@(Pandoc meta _) = do
228writeDocxPure opts doc@(Pandoc meta _) = do
232 let datadir = writerUserDataDir opts
229 let datadir = writerUserDataDir opts
233 let doc' = walk fixDisplayMath $ doc
230 let doc' = walk fixDisplayMath $ doc
@@ -614,7 +611,7 @@ styleToOpenXml sm style =
614 $ backgroundColor style )
611 $ backgroundColor style )
615 ]
612 ]
616
613
617−copyChildren :: Archive -> Archive -> String -> Integer -> [String] -> DocxAction Entry
614+copyChildren :: Archive -> Archive -> String -> Integer -> [String] -> PandocAction Entry
618copyChildren refArchive distArchive path timestamp elNames = do
615copyChildren refArchive distArchive path timestamp elNames = do
619 ref <- parseXml refArchive distArchive path
616 ref <- parseXml refArchive distArchive path
620 dist <- parseXml distArchive distArchive path
617 dist <- parseXml distArchive distArchive path
@@ -633,7 +630,7 @@ copyChildren refArchive distArchive path timestamp elNames = do
633baseListId :: Int
630baseListId :: Int
634baseListId = 1000
631baseListId = 1000
635
632
636−mkNumbering :: [ListMarker] -> DocxAction [Element]
633+mkNumbering :: [ListMarker] -> PandocAction [Element]
637mkNumbering lists = do
634mkNumbering lists = do
638 elts <- mapM mkAbstractNum (ordNub lists)
635 elts <- mapM mkAbstractNum (ordNub lists)
639 return $ elts ++ zipWith mkNum lists [baseListId..(baseListId + length lists - 1)]
636 return $ elts ++ zipWith mkNum lists [baseListId..(baseListId + length lists - 1)]
@@ -649,7 +646,7 @@ mkNum marker numid =
649 map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]
646 map (\lvl -> mknode "w:lvlOverride" [("w:ilvl",show (lvl :: Int))]
650 $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]
647 $ mknode "w:startOverride" [("w:val",show start)] ()) [0..6]
651
648
652−mkAbstractNum :: ListMarker -> DocxAction Element
649+mkAbstractNum :: ListMarker -> PandocAction Element
653mkAbstractNum marker = do
650mkAbstractNum marker = do
654 gen <- P.newStdGen
651 gen <- P.newStdGen
655 let (nsid, _) = randomR (0x10000000 :: Integer, 0xFFFFFFFF :: Integer) gen
652 let (nsid, _) = randomR (0x10000000 :: Integer, 0xFFFFFFFF :: Integer) gen
@@ -794,10 +791,10 @@ rStyleM styleName = do
794 let sty' = getStyleId styleName $ sCharStyleMap styleMaps
791 let sty' = getStyleId styleName $ sCharStyleMap styleMaps
795 return $ mknode "w:rStyle" [("w:val",sty')] ()
792 return $ mknode "w:rStyle" [("w:val",sty')] ()
796
793
797−getUniqueId :: DocxAction String
794+getUniqueId :: PandocAction String
798-- the + 20 is to ensure that there are no clashes with the rIds
795-- the + 20 is to ensure that there are no clashes with the rIds
799-- already in word/document.xml.rel
796-- already in word/document.xml.rel
800−getUniqueId = (show . (+ 20) . hashUnique) <$> P.newUnique
797+getUniqueId = (show . (+ 20)) <$> P.newUniqueHash
801
798
802-- | Key for specifying user-defined docx styles.
799-- | Key for specifying user-defined docx styles.
803dynamicStyleKey :: String
800dynamicStyleKey :: String
@@ -1284,7 +1281,7 @@ defaultFootnotes = [ mknode "w:footnote"
1284 [ mknode "w:r" [] $
1281 [ mknode "w:r" [] $
1285 [ mknode "w:continuationSeparator" [] ()]]]]
1282 [ mknode "w:continuationSeparator" [] ()]]]]
1286
1283
1287−parseXml :: Archive -> Archive -> String -> DocxAction Element
1284+parseXml :: Archive -> Archive -> String -> PandocAction Element
1288parseXml refArchive distArchive relpath =
1285parseXml refArchive distArchive relpath =
1289 case findEntryByPath relpath refArchive `mplus`
1286 case findEntryByPath relpath refArchive `mplus`
1290 findEntryByPath relpath distArchive of
1287 findEntryByPath relpath distArchive of
src/Text/Pandoc/Writers/EPUB.hs+3−5
@@ -66,8 +66,6 @@ import Text.HTML.TagSoup (Tag(TagOpen), fromAttrib, parseTags)
66import Text.Pandoc.Free (PandocAction, runIO)
66import Text.Pandoc.Free (PandocAction, runIO)
67import qualified Text.Pandoc.Free as P
67import qualified Text.Pandoc.Free as P
68
68
69−type EPUBAction = PandocAction [(FilePath, (FilePath, Maybe Entry))]
70−
71-- A Chapter includes a list of blocks and maybe a section
69-- A Chapter includes a list of blocks and maybe a section
72-- number offset. Note, some chapters are unnumbered. The section
70-- number offset. Note, some chapters are unnumbered. The section
73-- number is different from the index number, which will be used
71-- number is different from the index number, which will be used
@@ -77,7 +75,7 @@ data Chapter = Chapter (Maybe [Int]) [Block]
77data EPUBState = EPUBState { stMediaPaths :: [(FilePath, (FilePath, Maybe Entry))]
75data EPUBState = EPUBState { stMediaPaths :: [(FilePath, (FilePath, Maybe Entry))]
78 }
76 }
79
77
80−type E = StateT EPUBState EPUBAction
78+type E = StateT EPUBState PandocAction
81
79
82data EPUBMetadata = EPUBMetadata{
80data EPUBMetadata = EPUBMetadata{
83 epubIdentifier :: [Identifier]
81 epubIdentifier :: [Identifier]
@@ -343,7 +341,7 @@ writeEPUB opts doc = runIO $ writeEPUBPure opts doc
343
341
344writeEPUBPure :: WriterOptions -- ^ Writer options
342writeEPUBPure :: WriterOptions -- ^ Writer options
345 -> Pandoc -- ^ Document to convert
343 -> Pandoc -- ^ Document to convert
346− -> EPUBAction B.ByteString
344+ -> PandocAction B.ByteString
347writeEPUBPure opts doc =
345writeEPUBPure opts doc =
348 let initState = EPUBState { stMediaPaths = []
346 let initState = EPUBState { stMediaPaths = []
349 }
347 }
@@ -398,7 +396,7 @@ pandocToEPUB opts doc@(Pandoc meta _) = do
398 picEntries <- (catMaybes . map (snd . snd)) <$> (gets stMediaPaths)
396 picEntries <- (catMaybes . map (snd . snd)) <$> (gets stMediaPaths)
399 -- handle fonts
397 -- handle fonts
400 let matchingGlob f = do
398 let matchingGlob f = do
401− xs <- lift $ P.namesMatching f
399+ xs <- lift $ P.glob f
402 when (null xs) $
400 when (null xs) $
403 lift $ P.warn $ f ++ " did not match any font files."
401 lift $ P.warn $ f ++ " did not match any font files."
404 return xs
402 return xs
src/Text/Pandoc/Writers/ICML.hs+3−5
@@ -28,11 +28,9 @@ import Data.Text as Text (breakOnAll, pack)
28import Control.Monad.State
28import Control.Monad.State
29import Network.URI (isURI)
29import Network.URI (isURI)
30import qualified Data.Set as Set
30import qualified Data.Set as Set
31−import Text.Pandoc.Free (runIO)
31+import Text.Pandoc.Free (runIO, PandocAction)
32import qualified Text.Pandoc.Free as P
32import qualified Text.Pandoc.Free as P
33
33
34−type ICMLAction = P.PandocAction ()
35−
36type Style = [String]
34type Style = [String]
37type Hyperlink = [(Int, String)]
35type Hyperlink = [(Int, String)]
38
36
@@ -44,7 +42,7 @@ data WriterState = WriterState{
44 , maxListDepth :: Int
42 , maxListDepth :: Int
45 }
43 }
46
44
47−type WS a = StateT WriterState ICMLAction a
45+type WS a = StateT WriterState PandocAction a
48
46
49defaultWriterState :: WriterState
47defaultWriterState :: WriterState
50defaultWriterState = WriterState{
48defaultWriterState = WriterState{
@@ -130,7 +128,7 @@ writeICML :: WriterOptions -> Pandoc -> IO String
130writeICML opts doc = runIO $ writeICMLPure opts doc
128writeICML opts doc = runIO $ writeICMLPure opts doc
131
129
132-- | Convert Pandoc document to string in ICML format.
130-- | Convert Pandoc document to string in ICML format.
133−writeICMLPure :: WriterOptions -> Pandoc -> ICMLAction String
131+writeICMLPure :: WriterOptions -> Pandoc -> PandocAction String
134writeICMLPure opts (Pandoc meta blocks) = do
132writeICMLPure opts (Pandoc meta blocks) = do
135 let colwidth = if writerWrapText opts == WrapAuto
133 let colwidth = if writerWrapText opts == WrapAuto
136 then Just $ writerColumns opts
134 then Just $ writerColumns opts
src/Text/Pandoc/Writers/ODT.hs+2−4
@@ -53,12 +53,10 @@ import System.FilePath ( takeExtension, takeDirectory, (<.>))
53import Text.Pandoc.Free ( PandocAction, runIO )
53import Text.Pandoc.Free ( PandocAction, runIO )
54import qualified Text.Pandoc.Free as P
54import qualified Text.Pandoc.Free as P
55
55
56−type ODTAction = PandocAction [Entry]
57−
58data ODTState = ODTState { stEntries :: [Entry]
56data ODTState = ODTState { stEntries :: [Entry]
59 }
57 }
60
58
61−type O = StateT ODTState ODTAction
59+type O = StateT ODTState PandocAction
62
60
63-- | Produce an ODT file from a Pandoc document.
61-- | Produce an ODT file from a Pandoc document.
64writeODT :: WriterOptions -- ^ Writer options
62writeODT :: WriterOptions -- ^ Writer options
@@ -68,7 +66,7 @@ writeODT opts doc = runIO $ writeODTPure opts doc
68
66
69writeODTPure :: WriterOptions
67writeODTPure :: WriterOptions
70 -> Pandoc
68 -> Pandoc
71− -> ODTAction B.ByteString
69+ -> PandocAction B.ByteString
72writeODTPure opts doc =
70writeODTPure opts doc =
73 let initState = ODTState{ stEntries = []
71 let initState = ODTState{ stEntries = []
74 }
72 }