git.iko.soy/typeable/pandoc
on master help sign in
Switched Writer types to use Text.

* XML.toEntities: changed type to Text -> Text. * Shared.tabFilter -- fixed so it strips out CRs as before. * Modified writers to take Text. * Updated tests, benchmarks, trypandoc. [API change] Closes #3731.

commitfa719d026464619dd51714620470998ab5d18e17 authorJohn MacFarlane <jgm@berkeley.edu> dateSat 10 Jun 2017, 23:39 (9 years ago) parent0c2a509
48 files changed+292−210
benchmark/benchmark-pandoc.hs+5−5 benchmark/weigh-pandoc.hs+4−4 src/Text/Pandoc/App.hs+18−11 src/Text/Pandoc/PDF.hs+14−13 src/Text/Pandoc/Shared.hs+2−2 src/Text/Pandoc/Writers/AsciiDoc.hs+7−4 src/Text/Pandoc/Writers/CommonMark.hs+6−7 src/Text/Pandoc/Writers/ConTeXt.hs+8−5 src/Text/Pandoc/Writers/Custom.hs+5−3 src/Text/Pandoc/Writers/Docbook.hs+8−6 src/Text/Pandoc/Writers/DokuWiki.hs+4−3 src/Text/Pandoc/Writers/EPUB.hs+3−2 src/Text/Pandoc/Writers/FB2.hs+4−3 src/Text/Pandoc/Writers/HTML.hs+28−22 src/Text/Pandoc/Writers/Haddock.hs+6−5 src/Text/Pandoc/Writers/ICML.hs+3−1 src/Text/Pandoc/Writers/JATS.hs+7−5 src/Text/Pandoc/Writers/LaTeX.hs+10−7 src/Text/Pandoc/Writers/Man.hs+17−13 src/Text/Pandoc/Writers/Markdown.hs+13−10 src/Text/Pandoc/Writers/MediaWiki.hs+5−3 src/Text/Pandoc/Writers/Ms.hs+7−5 src/Text/Pandoc/Writers/Muse.hs+7−4 src/Text/Pandoc/Writers/Native.hs+2−1 src/Text/Pandoc/Writers/ODT.hs+3−2 src/Text/Pandoc/Writers/OPML.hs+9−6 src/Text/Pandoc/Writers/OpenDocument.hs+6−4 src/Text/Pandoc/Writers/Org.hs+7−4 src/Text/Pandoc/Writers/RST.hs+8−5 src/Text/Pandoc/Writers/RTF.hs+5−2 src/Text/Pandoc/Writers/TEI.hs+6−4 src/Text/Pandoc/Writers/Texinfo.hs+7−4 src/Text/Pandoc/Writers/Textile.hs+6−5 src/Text/Pandoc/Writers/ZimWiki.hs+4−4 src/Text/Pandoc/XML.hs+6−5 test/Tests/Helpers.hs+4−3 test/Tests/Readers/Docx.hs+2−1 test/Tests/Readers/LaTeX.hs+1−1 test/Tests/Readers/Odt.hs+3−1 test/Tests/Writers/AsciiDoc.hs+2−1 test/Tests/Writers/ConTeXt.hs+3−2 test/Tests/Writers/Docbook.hs+2−1 test/Tests/Writers/HTML.hs+2−1 test/Tests/Writers/LaTeX.hs+3−2 test/Tests/Writers/Markdown.hs+3−2 test/Tests/Writers/Muse.hs+2−1 test/Tests/Writers/Native.hs+3−3 trypandoc/trypandoc.hs+2−2
benchmark/benchmark-pandoc.hs+5−5
@@ -33,15 +33,15 @@ readerBench :: Pandoc
3333 -> Maybe Benchmark
3434readerBench doc (name, reader) =
3535 case lookup name writers of
36− Just (StringWriter writer) ->
37− let inp = either (error . show) pack $ runPure
36+ Just (TextWriter writer) ->
37+ let inp = either (error . show) id $ runPure
3838 $ writer def{ writerWrapText = WrapAuto} doc
3939 in return $ bench (name ++ " reader") $ nf
4040 (reader def) inp
4141 _ -> trace ("\nCould not find writer for " ++ name ++ "\n") Nothing
4242
4343writerBench :: Pandoc
44− -> (String, WriterOptions -> Pandoc -> String)
44+ -> (String, WriterOptions -> Pandoc -> Text)
4545 -> Benchmark
4646writerBench doc (name, writer) = bench (name ++ " writer") $ nf
4747 (writer def{ writerWrapText = WrapAuto }) doc
@@ -55,7 +55,7 @@ main = do
5555 [x] -> x == n
5656 (x:y:_) -> x == n && y == "reader"
5757 matchReader (_, _) = False
58− let matchWriter (n, StringWriter _) =
58+ let matchWriter (n, TextWriter _) =
5959 case args of
6060 [] -> True
6161 [x] -> x == n
@@ -81,7 +81,7 @@ main = do
8181 $ filter (\(n,_) -> n /="haddock") readers'
8282 let writers' = [(n, \o d ->
8383 either (error . show) id $ runPure $ setupFakeFiles >> w o d)
84− | (n, StringWriter w) <- matchedWriters]
84+ | (n, TextWriter w) <- matchedWriters]
8585 let writerBs = map (writerBench doc)
8686 $ writers'
8787 defaultMainWith defaultConfig{ timeLimit = 6.0 }
benchmark/weigh-pandoc.hs+4−4
@@ -1,6 +1,6 @@
11import Weigh
22import Text.Pandoc
3−import Data.Text (Text, pack)
3+import Data.Text (Text)
44
55main :: IO ()
66main = do
@@ -24,14 +24,14 @@ main = do
2424 ,("commonmark", writeCommonMark)
2525 ]
2626
27−weighWriter :: Pandoc -> String -> (Pandoc -> String) -> Weigh ()
27+weighWriter :: Pandoc -> String -> (Pandoc -> Text) -> Weigh ()
2828weighWriter doc name writer = func (name ++ " writer") writer doc
2929
3030weighReader :: Pandoc -> String -> (Text -> Pandoc) -> Weigh ()
3131weighReader doc name reader = do
3232 case lookup name writers of
33− Just (StringWriter writer) ->
34− let inp = either (error . show) pack $ runPure $ writer def{ writerWrapText = WrapAuto} doc
33+ Just (TextWriter writer) ->
34+ let inp = either (error . show) id $ runPure $ writer def{ writerWrapText = WrapAuto} doc
3535 in func (name ++ " reader") reader inp
3636 _ -> return () -- no writer for reader
3737
src/Text/Pandoc/App.hs+18−11
@@ -43,6 +43,7 @@ import qualified Control.Exception as E
4343import Control.Monad
4444import Control.Monad.Except (throwError)
4545import Control.Monad.Trans
46+import Data.Monoid
4647import Data.Aeson (FromJSON (..), ToJSON (..), defaultOptions, eitherDecode',
4748 encode, genericToEncoding)
4849import qualified Data.ByteString as BS
@@ -183,7 +184,7 @@ convertWithOpts opts = do
183184 -- disabling the custom writer for now
184185 writer <- if ".lua" `isSuffixOf` format
185186 -- note: use non-lowercased version writerName
186− then return (StringWriter
187+ then return (TextWriter
187188 (\o d -> liftIO $ writeCustom writerName o d)
188189 :: Writer PandocIO)
189190 else case getWriter writerName of
@@ -442,7 +443,7 @@ convertWithOpts opts = do
442443
443444 case writer of
444445 ByteStringWriter f -> f writerOptions doc >>= writeFnBinary outputFile
445− StringWriter f
446+ TextWriter f
446447 | pdfOutput -> do
447448 -- make sure writer is latex, beamer, context, html5 or ms
448449 unless (laTeXOutput || conTeXtOutput || html5Output ||
@@ -469,18 +470,23 @@ convertWithOpts opts = do
469470 | otherwise -> do
470471 let htmlFormat = format `elem`
471472 ["html","html4","html5","s5","slidy","slideous","dzslides","revealjs"]
472− selfcontain = if optSelfContained opts && htmlFormat
473− then makeSelfContained writerOptions
474− else return
475473 handleEntities = if (htmlFormat ||
476474 format == "docbook4" ||
477475 format == "docbook5" ||
478476 format == "docbook") && optAscii opts
479477 then toEntities
480478 else id
481− output <- f writerOptions doc
482− selfcontain (output ++ ['\n' | not standalone]) >>=
483− writerFn eol outputFile . handleEntities
479+ addNl = if standalone
480+ then id
481+ else (<> T.singleton '\n')
482+ output <- (addNl . handleEntities) <$> f writerOptions doc
483+ writerFn eol outputFile =<<
484+ if optSelfContained opts && htmlFormat
485+ -- TODO not maximally efficient; change type
486+ -- of makeSelfContained so it works w/ Text
487+ then T.pack <$> makeSelfContained writerOptions
488+ (T.unpack output)
489+ else return output
484490
485491type Transform = Pandoc -> Pandoc
486492
@@ -810,9 +816,10 @@ writeFnBinary :: MonadIO m => FilePath -> B.ByteString -> m ()
810816writeFnBinary "-" = liftIO . B.putStr
811817writeFnBinary f = liftIO . B.writeFile (UTF8.encodePath f)
812818
813−writerFn :: MonadIO m => IO.Newline -> FilePath -> String -> m ()
814−writerFn eol "-" = liftIO . UTF8.putStrWith eol
815−writerFn eol f = liftIO . UTF8.writeFileWith eol f
819+writerFn :: MonadIO m => IO.Newline -> FilePath -> Text -> m ()
820+-- TODO this implementation isn't maximally efficient:
821+writerFn eol "-" = liftIO . UTF8.putStrWith eol . T.unpack
822+writerFn eol f = liftIO . UTF8.writeFileWith eol f . T.unpack
816823
817824lookupHighlightStyle :: Maybe String -> IO (Maybe Style)
818825lookupHighlightStyle Nothing = return Nothing
src/Text/Pandoc/PDF.hs+14−13
@@ -36,12 +36,13 @@ import qualified Codec.Picture as JP
3636import qualified Control.Exception as E
3737import Control.Monad (unless, when)
3838import Control.Monad.Trans (MonadIO (..))
39+import qualified Data.Text as T
40+import Data.Text (Text)
3941import qualified Data.ByteString as BS
4042import Data.ByteString.Lazy (ByteString)
4143import qualified Data.ByteString.Lazy as B
4244import qualified Data.ByteString.Lazy as BL
4345import qualified Data.ByteString.Lazy.Char8 as BC
44−import Data.List (isInfixOf)
4546import Data.Maybe (fromMaybe)
4647import Data.Monoid ((<>))
4748import System.Directory
@@ -74,7 +75,7 @@ changePathSeparators = intercalate "/" . splitDirectories
7475
7576makePDF :: String -- ^ pdf creator (pdflatex, lualatex,
7677 -- xelatex, context, wkhtmltopdf, pdfroff)
77− -> (WriterOptions -> Pandoc -> PandocIO String) -- ^ writer
78+ -> (WriterOptions -> Pandoc -> PandocIO Text) -- ^ writer
7879 -> WriterOptions -- ^ options
7980 -> Verbosity -- ^ verbosity level
8081 -> MediaBag -- ^ media
@@ -178,10 +179,10 @@ tex2pdf' :: Verbosity -- ^ Verbosity level
178179 -> [String] -- ^ Arguments to the latex-engine
179180 -> FilePath -- ^ temp directory for output
180181 -> String -- ^ tex program
181− -> String -- ^ tex source
182+ -> Text -- ^ tex source
182183 -> IO (Either ByteString ByteString)
183184tex2pdf' verbosity args tmpDir program source = do
184− let numruns = if "\\tableofcontents" `isInfixOf` source
185+ let numruns = if "\\tableofcontents" `T.isInfixOf` source
185186 then 3 -- to get page numbers
186187 else 2 -- 1 run won't give you PDF bookmarks
187188 (exit, log', mbPdf) <- runTeXProgram verbosity program args 1 numruns tmpDir source
@@ -223,11 +224,11 @@ extractConTeXtMsg log' = do
223224-- contents of stdout, contents of produced PDF if any). Rerun
224225-- a fixed number of times to resolve references.
225226runTeXProgram :: Verbosity -> String -> [String] -> Int -> Int -> FilePath
226− -> String -> IO (ExitCode, ByteString, Maybe ByteString)
227+ -> Text -> IO (ExitCode, ByteString, Maybe ByteString)
227228runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
228229 let file = tmpDir </> "input.tex"
229230 exists <- doesFileExist file
230− unless exists $ UTF8.writeFile file source
231+ unless exists $ BS.writeFile file $ UTF8.fromText source
231232#ifdef _WINDOWS
232233 -- note: we want / even on Windows, for TexLive
233234 let tmpDir' = changePathSeparators tmpDir
@@ -276,7 +277,7 @@ runTeXProgram verbosity program args runNumber numRuns tmpDir source = do
276277
277278ms2pdf :: Verbosity
278279 -> [String]
279− -> String
280+ -> Text
280281 -> IO (Either ByteString ByteString)
281282ms2pdf verbosity args source = do
282283 env' <- getEnvironment
@@ -288,10 +289,10 @@ ms2pdf verbosity args source = do
288289 mapM_ print env'
289290 putStr "\n"
290291 putStrLn $ "[makePDF] Contents:\n"
291− putStr source
292+ putStr $ T.unpack source
292293 putStr "\n"
293294 (exit, out) <- pipeProcess (Just env') "pdfroff" args
294− (UTF8.fromStringLazy source)
295+ (BL.fromStrict $ UTF8.fromText source)
295296 when (verbosity >= INFO) $ do
296297 B.hPutStr stdout out
297298 putStr "\n"
@@ -301,12 +302,12 @@ ms2pdf verbosity args source = do
301302
302303html2pdf :: Verbosity -- ^ Verbosity level
303304 -> [String] -- ^ Args to wkhtmltopdf
304− -> String -- ^ HTML5 source
305+ -> Text -- ^ HTML5 source
305306 -> IO (Either ByteString ByteString)
306307html2pdf verbosity args source = do
307308 file <- withTempFile "." "html2pdf.html" $ \fp _ -> return fp
308309 pdfFile <- withTempFile "." "html2pdf.pdf" $ \fp _ -> return fp
309− UTF8.writeFile file source
310+ BS.writeFile file $ UTF8.fromText source
310311 let programArgs = args ++ [file, pdfFile]
311312 env' <- getEnvironment
312313 when (verbosity >= INFO) $ do
@@ -341,11 +342,11 @@ html2pdf verbosity args source = do
341342
342343context2pdf :: Verbosity -- ^ Verbosity level
343344 -> FilePath -- ^ temp directory for output
344− -> String -- ^ ConTeXt source
345+ -> Text -- ^ ConTeXt source
345346 -> IO (Either ByteString ByteString)
346347context2pdf verbosity tmpDir source = inDirectory tmpDir $ do
347348 let file = "input.tex"
348− UTF8.writeFile file source
349+ BS.writeFile file $ UTF8.fromText source
349350#ifdef _WINDOWS
350351 -- note: we want / even on Windows, for TexLive
351352 let tmpDir' = changePathSeparators tmpDir
src/Text/Pandoc/Shared.hs+2−2
@@ -284,8 +284,8 @@ escapeURI = escapeURIString (not . needsEscaping)
284284tabFilter :: Int -- ^ Tab stop
285285 -> T.Text -- ^ Input
286286 -> T.Text
287−tabFilter tabStop =
288− T.unlines . (if tabStop == 0 then id else map go) . T.lines
287+tabFilter tabStop = T.filter (/= '\r') . T.unlines .
288+ (if tabStop == 0 then id else map go) . T.lines
289289 where go s =
290290 let (s1, s2) = T.break (== '\t') s
291291 in if T.null s2
src/Text/Pandoc/Writers/AsciiDoc.hs+7−4
@@ -43,6 +43,7 @@ import Data.Char (isPunctuation, isSpace)
4343import Data.List (intercalate, intersperse, stripPrefix)
4444import qualified Data.Map as M
4545import Data.Maybe (fromMaybe)
46+import Data.Text (Text)
4647import qualified Data.Text as T
4748import Text.Pandoc.Class (PandocMonad, report)
4849import Text.Pandoc.Definition
@@ -62,7 +63,7 @@ data WriterState = WriterState { defListMarker :: String
6263 }
6364
6465-- | Convert Pandoc to AsciiDoc.
65−writeAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> m String
66+writeAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6667writeAsciiDoc opts document =
6768 evalStateT (pandocToAsciiDoc opts document) WriterState{
6869 defListMarker = "::"
@@ -74,16 +75,18 @@ writeAsciiDoc opts document =
7475type ADW = StateT WriterState
7576
7677-- | Return asciidoc representation of document.
77−pandocToAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> ADW m String
78+pandocToAsciiDoc :: PandocMonad m => WriterOptions -> Pandoc -> ADW m Text
7879pandocToAsciiDoc opts (Pandoc meta blocks) = do
7980 let titleblock = not $ null (docTitle meta) && null (docAuthors meta) &&
8081 null (docDate meta)
8182 let colwidth = if writerWrapText opts == WrapAuto
8283 then Just $ writerColumns opts
8384 else Nothing
85+ let render' :: Doc -> Text
86+ render' = render colwidth
8487 metadata <- metaToJSON opts
85− (fmap (render colwidth) . blockListToAsciiDoc opts)
86− (fmap (render colwidth) . inlineListToAsciiDoc opts)
88+ (fmap render' . blockListToAsciiDoc opts)
89+ (fmap render' . inlineListToAsciiDoc opts)
8790 meta
8891 let addTitleLine (String t) = String $
8992 t <> "\n" <> T.replicate (T.length t) "="
src/Text/Pandoc/Writers/CommonMark.hs+6−7
@@ -34,6 +34,7 @@ module Text.Pandoc.Writers.CommonMark (writeCommonMark) where
3434import CMark
3535import Control.Monad.State (State, get, modify, runState)
3636import Data.Foldable (foldrM)
37+import Data.Text (Text)
3738import qualified Data.Text as T
3839import Text.Pandoc.Class (PandocMonad)
3940import Text.Pandoc.Definition
@@ -45,7 +46,7 @@ import Text.Pandoc.Writers.HTML (writeHtml5String)
4546import Text.Pandoc.Writers.Shared
4647
4748-- | Convert Pandoc to CommonMark.
48−writeCommonMark :: PandocMonad m => WriterOptions -> Pandoc -> m String
49+writeCommonMark :: PandocMonad m => WriterOptions -> Pandoc -> m Text
4950writeCommonMark opts (Pandoc meta blocks) = do
5051 let (blocks', notes) = runState (walkM processNotes blocks) []
5152 notes' = if null notes
@@ -71,7 +72,7 @@ processNotes x = return x
7172node :: NodeType -> [Node] -> Node
7273node = Node Nothing
7374
74−blocksToCommonMark :: PandocMonad m => WriterOptions -> [Block] -> m String
75+blocksToCommonMark :: PandocMonad m => WriterOptions -> [Block] -> m Text
7576blocksToCommonMark opts bs = do
7677 let cmarkOpts = [optHardBreaks | isEnabled Ext_hard_line_breaks opts]
7778 colwidth = if writerWrapText opts == WrapAuto
@@ -79,14 +80,12 @@ blocksToCommonMark opts bs = do
7980 else Nothing
8081 nodes <- blocksToNodes bs
8182 return $
82− T.unpack $
8383 nodeToCommonmark cmarkOpts colwidth $
8484 node DOCUMENT nodes
8585
86−inlinesToCommonMark :: PandocMonad m => WriterOptions -> [Inline] -> m String
86+inlinesToCommonMark :: PandocMonad m => WriterOptions -> [Inline] -> m Text
8787inlinesToCommonMark opts ils = return $
88− T.unpack $ nodeToCommonmark cmarkOpts colwidth
89− $ node PARAGRAPH (inlinesToNodes ils)
88+ nodeToCommonmark cmarkOpts colwidth $ node PARAGRAPH (inlinesToNodes ils)
9089 where cmarkOpts = [optHardBreaks | isEnabled Ext_hard_line_breaks opts]
9190 colwidth = if writerWrapText opts == WrapAuto
9291 then Just $ writerColumns opts
@@ -139,7 +138,7 @@ blockToNodes (DefinitionList items) ns = blockToNodes (BulletList items') ns
139138 Para term : concat xs
140139blockToNodes t@(Table _ _ _ _ _) ns = do
141140 s <- writeHtml5String def $! Pandoc nullMeta [t]
142− return (node (HTML_BLOCK (T.pack $! s)) [] : ns)
141+ return (node (HTML_BLOCK s) [] : ns)
143142blockToNodes Null ns = return ns
144143
145144inlinesToNodes :: [Inline] -> [Node]
src/Text/Pandoc/Writers/ConTeXt.hs+8−5
@@ -33,6 +33,7 @@ import Control.Monad.State
3333import Data.Char (ord)
3434import Data.List (intercalate, intersperse)
3535import Data.Maybe (catMaybes)
36+import Data.Text (Text)
3637import Network.URI (unEscapeString)
3738import Text.Pandoc.Class (PandocMonad, report)
3839import Text.Pandoc.Logging
@@ -56,7 +57,7 @@ orderedListStyles :: [Char]
5657orderedListStyles = cycle "narg"
5758
5859-- | Convert Pandoc to ConTeXt.
59−writeConTeXt :: PandocMonad m => WriterOptions -> Pandoc -> m String
60+writeConTeXt :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6061writeConTeXt options document =
6162 let defaultWriterState = WriterState { stNextRef = 1
6263 , stOrderedListLevel = 0
@@ -66,17 +67,19 @@ writeConTeXt options document =
6667
6768type WM = StateT WriterState
6869
69−pandocToConTeXt :: PandocMonad m => WriterOptions -> Pandoc -> WM m String
70+pandocToConTeXt :: PandocMonad m => WriterOptions -> Pandoc -> WM m Text
7071pandocToConTeXt options (Pandoc meta blocks) = do
7172 let colwidth = if writerWrapText options == WrapAuto
7273 then Just $ writerColumns options
7374 else Nothing
75+ let render' :: Doc -> Text
76+ render' = render colwidth
7477 metadata <- metaToJSON options
75− (fmap (render colwidth) . blockListToConTeXt)
76− (fmap (render colwidth) . inlineListToConTeXt)
78+ (fmap render' . blockListToConTeXt)
79+ (fmap render' . inlineListToConTeXt)
7780 meta
7881 body <- mapM (elementToConTeXt options) $ hierarchicalize blocks
79− let main = (render colwidth . vcat) body
82+ let main = (render' . vcat) body
8083 let layoutFromMargins = intercalate [','] $ catMaybes $
8184 map (\(x,y) ->
8285 ((x ++ "=") ++) <$> getField y metadata)
src/Text/Pandoc/Writers/Custom.hs+5−3
@@ -41,6 +41,7 @@ import Control.Monad (when)
4141import Data.Char (toLower)
4242import Data.List (intersperse)
4343import qualified Data.Map as M
44+import Data.Text (Text, pack)
4445import Data.Typeable
4546import GHC.IO.Encoding (getForeignEncoding, setForeignEncoding, utf8)
4647import Scripting.Lua (LuaState, StackValue, callfunc)
@@ -116,7 +117,7 @@ data PandocLuaException = PandocLuaException String
116117instance Exception PandocLuaException
117118
118119-- | Convert Pandoc to custom markup.
119−writeCustom :: FilePath -> WriterOptions -> Pandoc -> IO String
120+writeCustom :: FilePath -> WriterOptions -> Pandoc -> IO Text
120121writeCustom luaFile opts doc@(Pandoc meta _) = do
121122 luaScript <- UTF8.readFile luaFile
122123 enc <- getForeignEncoding
@@ -139,8 +140,9 @@ writeCustom luaFile opts doc@(Pandoc meta _) = do
139140 setForeignEncoding enc
140141 let body = rendered
141142 case writerTemplate opts of
142− Nothing -> return body
143− Just tpl -> return $ renderTemplate' tpl $ setField "body" body context
143+ Nothing -> return $ pack body
144+ Just tpl -> return $ pack $
145+ renderTemplate' tpl $ setField "body" body context
144146
145147docToCustom :: LuaState -> WriterOptions -> Pandoc -> IO String
146148docToCustom lua opts (Pandoc (Meta metamap) blocks) = do
src/Text/Pandoc/Writers/Docbook.hs+8−6
@@ -32,6 +32,7 @@ Conversion of 'Pandoc' documents to Docbook XML.
3232module Text.Pandoc.Writers.Docbook ( writeDocbook4, writeDocbook5 ) where
3333import Control.Monad.Reader
3434import Data.Char (toLower)
35+import Data.Text (Text)
3536import Data.Generics (everywhere, mkT)
3637import Data.List (intercalate, isPrefixOf, isSuffixOf, stripPrefix)
3738import Data.Monoid (Any (..))
@@ -81,22 +82,23 @@ authorToDocbook opts name' = do
8182 in inTagsSimple "firstname" (text $ escapeStringForXML firstname) $$
8283 inTagsSimple "surname" (text $ escapeStringForXML lastname)
8384
84−writeDocbook4 :: PandocMonad m => WriterOptions -> Pandoc -> m String
85+writeDocbook4 :: PandocMonad m => WriterOptions -> Pandoc -> m Text
8586writeDocbook4 opts d =
8687 runReaderT (writeDocbook opts d) DocBook4
8788
88−writeDocbook5 :: PandocMonad m => WriterOptions -> Pandoc -> m String
89+writeDocbook5 :: PandocMonad m => WriterOptions -> Pandoc -> m Text
8990writeDocbook5 opts d =
9091 runReaderT (writeDocbook opts d) DocBook5
9192
9293-- | Convert Pandoc document to string in Docbook format.
93−writeDocbook :: PandocMonad m => WriterOptions -> Pandoc -> DB m String
94+writeDocbook :: PandocMonad m => WriterOptions -> Pandoc -> DB m Text
9495writeDocbook opts (Pandoc meta blocks) = do
9596 let elements = hierarchicalize blocks
9697 let colwidth = if writerWrapText opts == WrapAuto
9798 then Just $ writerColumns opts
9899 else Nothing
99− let render' = render colwidth
100+ let render' :: Doc -> Text
101+ render' = render colwidth
100102 let opts' = if (maybe False (("/book>" `isSuffixOf`) . trimr)
101103 (writerTemplate opts) &&
102104 TopLevelDefault == writerTopLevelDivision opts)
@@ -111,10 +113,10 @@ writeDocbook opts (Pandoc meta blocks) = do
111113 auths' <- mapM (authorToDocbook opts) $ docAuthors meta
112114 let meta' = B.setMeta "author" auths' meta
113115 metadata <- metaToJSON opts
114− (fmap (render colwidth . vcat) .
116+ (fmap (render' . vcat) .
115117 (mapM (elementToDocbook opts' startLvl) .
116118 hierarchicalize))
117− (fmap (render colwidth) . inlinesToDocbook opts')
119+ (fmap render' . inlinesToDocbook opts')
118120 meta'
119121 main <- (render' . vcat) <$> (mapM (elementToDocbook opts' startLvl) elements)
120122 let context = defField "body" main
src/Text/Pandoc/Writers/DokuWiki.hs+4−3
@@ -44,6 +44,7 @@ import Control.Monad.Reader (ReaderT, ask, local, runReaderT)
4444import Control.Monad.State (StateT, evalStateT, gets, modify)
4545import Data.Default (Default (..))
4646import Data.List (intercalate, intersect, isPrefixOf, transpose)
47+import Data.Text (Text, pack)
4748import Text.Pandoc.Class (PandocMonad, report)
4849import Text.Pandoc.Logging
4950import Text.Pandoc.Definition
@@ -75,7 +76,7 @@ instance Default WriterEnvironment where
7576type DokuWiki m = ReaderT WriterEnvironment (StateT WriterState m)
7677
7778-- | Convert Pandoc to DokuWiki.
78−writeDokuWiki :: PandocMonad m => WriterOptions -> Pandoc -> m String
79+writeDokuWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
7980writeDokuWiki opts document =
8081 runDokuWiki (pandocToDokuWiki opts document)
8182
@@ -84,7 +85,7 @@ runDokuWiki = flip evalStateT def . flip runReaderT def
8485
8586-- | Return DokuWiki representation of document.
8687pandocToDokuWiki :: PandocMonad m
87− => WriterOptions -> Pandoc -> DokuWiki m String
88+ => WriterOptions -> Pandoc -> DokuWiki m Text
8889pandocToDokuWiki opts (Pandoc meta blocks) = do
8990 metadata <- metaToJSON opts
9091 (fmap trimr . blockListToDokuWiki opts)
@@ -96,7 +97,7 @@ pandocToDokuWiki opts (Pandoc meta blocks) = do
9697 then "" -- TODO Was "\n<references />" Check whether I can really remove this:
9798 -- if it is definitely to do with footnotes, can remove this whole bit
9899 else ""
99− let main = body ++ notes
100+ let main = pack $ body ++ notes
100101 let context = defField "body" main
101102 $ defField "toc" (writerTableOfContents opts)
102103 $ metadata
src/Text/Pandoc/Writers/EPUB.hs+3−2
@@ -40,6 +40,7 @@ import Control.Monad.State (State, StateT, evalState, evalStateT, get, gets,
4040 lift, modify, put)
4141import qualified Data.ByteString.Lazy as B
4242import qualified Data.ByteString.Lazy.Char8 as B8
43+import qualified Data.Text.Lazy as TL
4344import Data.Char (isAlphaNum, isDigit, toLower)
4445import Data.List (intercalate, isInfixOf, isPrefixOf)
4546import qualified Data.Map as M
@@ -373,8 +374,8 @@ pandocToEPUB :: PandocMonad m
373374 -> E m B.ByteString
374375pandocToEPUB version opts doc@(Pandoc meta _) = do
375376 let epub3 = version == EPUB3
376− let writeHtml o = fmap UTF8.fromStringLazy .
377− writeHtmlStringForEPUB version o
377+ let writeHtml o = fmap (UTF8.fromTextLazy . TL.fromStrict) .
378+ writeHtmlStringForEPUB version o
378379 epochtime <- floor <$> lift P.getPOSIXTime
379380 metadata <- getEPUBMetadata opts meta
380381 let mkEntry path content = toEntry path epochtime content
src/Text/Pandoc/Writers/FB2.hs+4−3
@@ -44,6 +44,7 @@ import Data.ByteString.Base64 (encode)
4444import qualified Data.ByteString.Char8 as B8
4545import Data.Char (isAscii, isControl, isSpace, toLower)
4646import Data.Either (lefts, rights)
47+import Data.Text (Text, pack)
4748import Data.List (intercalate, intersperse, isPrefixOf, stripPrefix)
4849import Network.HTTP (urlEncode)
4950import Text.XML.Light
@@ -86,13 +87,13 @@ instance Show ImageMode where
8687writeFB2 :: PandocMonad m
8788 => WriterOptions -- ^ conversion options
8889 -> Pandoc -- ^ document to convert
89− -> m String -- ^ FictionBook2 document (not encoded yet)
90+ -> m Text -- ^ FictionBook2 document (not encoded yet)
9091writeFB2 opts doc = flip evalStateT newFB $ pandocToFB2 opts doc
9192
9293pandocToFB2 :: PandocMonad m
9394 => WriterOptions
9495 -> Pandoc
95− -> FBM m String
96+ -> FBM m Text
9697pandocToFB2 opts (Pandoc meta blocks) = do
9798 modify (\s -> s { writerOptions = opts })
9899 desc <- description meta
@@ -103,7 +104,7 @@ pandocToFB2 opts (Pandoc meta blocks) = do
103104 (imgs,missing) <- liftM imagesToFetch get >>= \s -> lift (fetchImages s)
104105 let body' = replaceImagesWithAlt missing body
105106 let fb2_xml = el "FictionBook" (fb2_attrs, [desc, body'] ++ notes ++ imgs)
106− return $ xml_head ++ (showContent fb2_xml) ++ "\n"
107+ return $ pack $ xml_head ++ (showContent fb2_xml) ++ "\n"
107108 where
108109 xml_head = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
109110 fb2_attrs =
src/Text/Pandoc/Writers/HTML.hs+28−22
@@ -45,6 +45,8 @@ module Text.Pandoc.Writers.HTML (
4545 ) where
4646import Control.Monad.State
4747import Data.Char (ord, toLower)
48+import Data.Text (Text)
49+import qualified Data.Text.Lazy as TL
4850import Data.List (intersperse, isPrefixOf)
4951import Data.Maybe (catMaybes, fromMaybe, isJust, isNothing)
5052import Data.Monoid ((<>))
@@ -67,7 +69,7 @@ import Text.Pandoc.Writers.Shared
6769import Text.Pandoc.XML (escapeStringForXML, fromEntities)
6870#if MIN_VERSION_blaze_markup(0,6,3)
6971#else
70−import Text.Blaze.Internal (preEscapedString)
72+import Text.Blaze.Internal (preEscapedString, preEscapedText)
7173#endif
7274#if MIN_VERSION_blaze_html(0,5,1)
7375import qualified Text.Blaze.XHtml5 as H5
@@ -77,7 +79,7 @@ import qualified Text.Blaze.Html5 as H5
7779import Control.Monad.Except (throwError)
7880import Data.Aeson (Value)
7981import System.FilePath (takeExtension, takeBaseName)
80−import Text.Blaze.Html.Renderer.String (renderHtml)
82+import Text.Blaze.Html.Renderer.Text (renderHtml)
8183import qualified Text.Blaze.XHtml1.Transitional as H
8284import qualified Text.Blaze.XHtml1.Transitional.Attributes as A
8385import Text.Pandoc.Class (PandocMonad, report)
@@ -123,7 +125,7 @@ nl opts = if writerWrapText opts == WrapNone
123125 else preEscapedString "\n"
124126
125127-- | Convert Pandoc document to Html 5 string.
126−writeHtml5String :: PandocMonad m => WriterOptions -> Pandoc -> m String
128+writeHtml5String :: PandocMonad m => WriterOptions -> Pandoc -> m Text
127129writeHtml5String = writeHtmlString'
128130 defaultWriterState{ stHtml5 = True }
129131
@@ -132,7 +134,7 @@ writeHtml5 :: PandocMonad m => WriterOptions -> Pandoc -> m Html
132134writeHtml5 = writeHtml' defaultWriterState{ stHtml5 = True }
133135
134136-- | Convert Pandoc document to Html 4 string.
135−writeHtml4String :: PandocMonad m => WriterOptions -> Pandoc -> m String
137+writeHtml4String :: PandocMonad m => WriterOptions -> Pandoc -> m Text
136138writeHtml4String = writeHtmlString'
137139 defaultWriterState{ stHtml5 = False }
138140
@@ -142,38 +144,39 @@ writeHtml4 = writeHtml' defaultWriterState{ stHtml5 = False }
142144
143145-- | Convert Pandoc document to Html appropriate for an epub version.
144146writeHtmlStringForEPUB :: PandocMonad m
145− => EPUBVersion -> WriterOptions -> Pandoc -> m String
146−writeHtmlStringForEPUB version = writeHtmlString'
147+ => EPUBVersion -> WriterOptions -> Pandoc
148+ -> m Text
149+writeHtmlStringForEPUB version o = writeHtmlString'
147150 defaultWriterState{ stHtml5 = version == EPUB3,
148− stEPUBVersion = Just version }
151+ stEPUBVersion = Just version } o
149152
150153-- | Convert Pandoc document to Reveal JS HTML slide show.
151154writeRevealJs :: PandocMonad m
152− => WriterOptions -> Pandoc -> m String
155+ => WriterOptions -> Pandoc -> m Text
153156writeRevealJs = writeHtmlSlideShow' RevealJsSlides
154157
155158-- | Convert Pandoc document to S5 HTML slide show.
156159writeS5 :: PandocMonad m
157− => WriterOptions -> Pandoc -> m String
160+ => WriterOptions -> Pandoc -> m Text
158161writeS5 = writeHtmlSlideShow' S5Slides
159162
160163-- | Convert Pandoc document to Slidy HTML slide show.
161164writeSlidy :: PandocMonad m
162− => WriterOptions -> Pandoc -> m String
165+ => WriterOptions -> Pandoc -> m Text
163166writeSlidy = writeHtmlSlideShow' SlidySlides
164167
165168-- | Convert Pandoc document to Slideous HTML slide show.
166169writeSlideous :: PandocMonad m
167− => WriterOptions -> Pandoc -> m String
170+ => WriterOptions -> Pandoc -> m Text
168171writeSlideous = writeHtmlSlideShow' SlideousSlides
169172
170173-- | Convert Pandoc document to DZSlides HTML slide show.
171174writeDZSlides :: PandocMonad m
172− => WriterOptions -> Pandoc -> m String
175+ => WriterOptions -> Pandoc -> m Text
173176writeDZSlides = writeHtmlSlideShow' DZSlides
174177
175178writeHtmlSlideShow' :: PandocMonad m
176− => HTMLSlideVariant -> WriterOptions -> Pandoc -> m String
179+ => HTMLSlideVariant -> WriterOptions -> Pandoc -> m Text
177180writeHtmlSlideShow' variant = writeHtmlString'
178181 defaultWriterState{ stSlideVariant = variant
179182 , stHtml5 = case variant of
@@ -185,12 +188,15 @@ writeHtmlSlideShow' variant = writeHtmlString'
185188 NoSlides -> False
186189 }
187190
191+renderHtml' :: Html -> Text
192+renderHtml' = TL.toStrict . renderHtml
193+
188194writeHtmlString' :: PandocMonad m
189− => WriterState -> WriterOptions -> Pandoc -> m String
195+ => WriterState -> WriterOptions -> Pandoc -> m Text
190196writeHtmlString' st opts d = do
191197 (body, context) <- evalStateT (pandocToHtml opts d) st
192198 case writerTemplate opts of
193− Nothing -> return $ renderHtml body
199+ Nothing -> return $ renderHtml' body
194200 Just tpl -> do
195201 -- warn if empty lang
196202 when (isNothing (getField "lang" context :: Maybe String)) $
@@ -205,12 +211,12 @@ writeHtmlString' st opts d = do
205211 report $ NoTitleElement fallback
206212 return $ resetField "pagetitle" fallback context
207213 return $ renderTemplate' tpl $
208− defField "body" (renderHtml body) context'
214+ defField "body" (renderHtml' body) context'
209215
210216writeHtml' :: PandocMonad m => WriterState -> WriterOptions -> Pandoc -> m Html
211217writeHtml' st opts d = do
212218 case writerTemplate opts of
213− Just _ -> preEscapedString <$> writeHtmlString' st opts d
219+ Just _ -> preEscapedText <$> writeHtmlString' st opts d
214220 Nothing -> do
215221 (body, _) <- evalStateT (pandocToHtml opts d) st
216222 return body
@@ -222,8 +228,8 @@ pandocToHtml :: PandocMonad m
222228 -> StateT WriterState m (Html, Value)
223229pandocToHtml opts (Pandoc meta blocks) = do
224230 metadata <- metaToJSON opts
225− (fmap renderHtml . blockListToHtml opts)
226− (fmap renderHtml . inlineListToHtml opts)
231+ (fmap renderHtml' . blockListToHtml opts)
232+ (fmap renderHtml' . inlineListToHtml opts)
227233 meta
228234 let stringifyHTML = escapeStringForXML . stringify
229235 let authsMeta = map stringifyHTML $ docAuthors meta
@@ -277,10 +283,10 @@ pandocToHtml opts (Pandoc meta blocks) = do
277283 Nothing -> id
278284 else id) $
279285 (if stMath st
280− then defField "math" (renderHtml math)
286+ then defField "math" (renderHtml' math)
281287 else id) $
282288 defField "quotes" (stQuotes st) $
283− maybe id (defField "toc" . renderHtml) toc $
289+ maybe id (defField "toc" . renderHtml') toc $
284290 defField "author-meta" authsMeta $
285291 maybe id (defField "date-meta") (normalizeDate dateMeta) $
286292 defField "pagetitle" (stringifyHTML (docTitle meta)) $
@@ -463,7 +469,7 @@ parseMailto s = do
463469obfuscateLink :: PandocMonad m => WriterOptions -> Attr -> Html -> String -> m Html
464470obfuscateLink opts attr txt s | writerEmailObfuscation opts == NoObfuscation =
465471 return $ addAttrs opts attr $ H.a ! A.href (toValue s) $ txt
466−obfuscateLink opts attr (renderHtml -> txt) s =
472+obfuscateLink opts attr (TL.unpack . renderHtml -> txt) s =
467473 let meth = writerEmailObfuscation opts
468474 s' = map toLower (take 7 s) ++ drop 7 s
469475 in case parseMailto s' of
src/Text/Pandoc/Writers/Haddock.hs+6−5
@@ -35,6 +35,7 @@ Haddock: <http://www.haskell.org/haddock/doc/html/>
3535module Text.Pandoc.Writers.Haddock (writeHaddock) where
3636import Control.Monad.State
3737import Data.Default
38+import Data.Text (Text)
3839import Data.List (intersperse, transpose)
3940import Text.Pandoc.Class (PandocMonad, report)
4041import Text.Pandoc.Definition
@@ -52,14 +53,14 @@ instance Default WriterState
5253 where def = WriterState{ stNotes = [] }
5354
5455-- | Convert Pandoc to Haddock.
55−writeHaddock :: PandocMonad m => WriterOptions -> Pandoc -> m String
56+writeHaddock :: PandocMonad m => WriterOptions -> Pandoc -> m Text
5657writeHaddock opts document =
5758 evalStateT (pandocToHaddock opts{
5859 writerWrapText = writerWrapText opts } document) def
5960
6061-- | Return haddock representation of document.
6162pandocToHaddock :: PandocMonad m
62− => WriterOptions -> Pandoc -> StateT WriterState m String
63+ => WriterOptions -> Pandoc -> StateT WriterState m Text
6364pandocToHaddock opts (Pandoc meta blocks) = do
6465 let colwidth = if writerWrapText opts == WrapAuto
6566 then Just $ writerColumns opts
@@ -67,13 +68,13 @@ pandocToHaddock opts (Pandoc meta blocks) = do
6768 body <- blockListToHaddock opts blocks
6869 st <- get
6970 notes' <- notesToHaddock opts (reverse $ stNotes st)
70− let render' :: Doc -> String
71+ let render' :: Doc -> Text
7172 render' = render colwidth
7273 let main = render' $ body <>
7374 (if isEmpty notes' then empty else blankline <> notes')
7475 metadata <- metaToJSON opts
75− (fmap (render colwidth) . blockListToHaddock opts)
76− (fmap (render colwidth) . inlineListToHaddock opts)
76+ (fmap render' . blockListToHaddock opts)
77+ (fmap render' . inlineListToHaddock opts)
7778 meta
7879 let context = defField "body" main
7980 $ metadata
src/Text/Pandoc/Writers/ICML.hs+3−1
@@ -21,6 +21,7 @@ import Control.Monad.State
2121import Data.List (intersperse, isInfixOf, isPrefixOf, stripPrefix)
2222import qualified Data.Set as Set
2323import Data.Text as Text (breakOnAll, pack)
24+import Data.Text (Text)
2425import Text.Pandoc.Class (PandocMonad, report)
2526import qualified Text.Pandoc.Class as P
2627import Text.Pandoc.Definition
@@ -127,11 +128,12 @@ footnoteName = "Footnote"
127128citeName = "Cite"
128129
129130-- | Convert Pandoc document to string in ICML format.
130−writeICML :: PandocMonad m => WriterOptions -> Pandoc -> m String
131+writeICML :: PandocMonad m => WriterOptions -> Pandoc -> m Text
131132writeICML opts (Pandoc meta blocks) = do
132133 let colwidth = if writerWrapText opts == WrapAuto
133134 then Just $ writerColumns opts
134135 else Nothing
136+ render' :: Doc -> Text
135137 render' = render colwidth
136138 renderMeta f s = liftM (render' . fst) $ runStateT (f opts [] s) defaultWriterState
137139 metadata <- metaToJSON opts
src/Text/Pandoc/Writers/JATS.hs+7−5
@@ -33,6 +33,7 @@ https://jats.nlm.nih.gov/publishing/tag-library/1.1d3/element/mml-math.html
3333module Text.Pandoc.Writers.JATS ( writeJATS ) where
3434import Control.Monad.Reader
3535import Data.Char (toLower)
36+import Data.Text (Text)
3637import Data.Generics (everywhere, mkT)
3738import Data.List (intercalate, isSuffixOf, partition)
3839import Data.Maybe (fromMaybe)
@@ -81,12 +82,12 @@ authorToJATS opts name' = do
8182 in inTagsSimple "firstname" (text $ escapeStringForXML firstname) $$
8283 inTagsSimple "surname" (text $ escapeStringForXML lastname)
8384
84−writeJATS :: PandocMonad m => WriterOptions -> Pandoc -> m String
85+writeJATS :: PandocMonad m => WriterOptions -> Pandoc -> m Text
8586writeJATS opts d =
8687 runReaderT (docToJATS opts d) JATS1_1
8788
8889-- | Convert Pandoc document to string in JATS format.
89−docToJATS :: PandocMonad m => WriterOptions -> Pandoc -> DB m String
90+docToJATS :: PandocMonad m => WriterOptions -> Pandoc -> DB m Text
9091docToJATS opts (Pandoc meta blocks) = do
9192 let isBackBlock (Div ("refs",_,_) _) = True
9293 isBackBlock _ = False
@@ -96,7 +97,8 @@ docToJATS opts (Pandoc meta blocks) = do
9697 let colwidth = if writerWrapText opts == WrapAuto
9798 then Just $ writerColumns opts
9899 else Nothing
99− let render' = render colwidth
100+ let render' :: Doc -> Text
101+ render' = render colwidth
100102 let opts' = if (maybe False (("/book>" `isSuffixOf`) . trimr)
101103 (writerTemplate opts) &&
102104 TopLevelDefault == writerTopLevelDivision opts)
@@ -111,10 +113,10 @@ docToJATS opts (Pandoc meta blocks) = do
111113 auths' <- mapM (authorToJATS opts) $ docAuthors meta
112114 let meta' = B.setMeta "author" auths' meta
113115 metadata <- metaToJSON opts
114− (fmap (render colwidth . vcat) .
116+ (fmap (render' . vcat) .
115117 (mapM (elementToJATS opts' startLvl) .
116118 hierarchicalize))
117− (fmap (render colwidth) . inlinesToJATS opts')
119+ (fmap render' . inlinesToJATS opts')
118120 meta'
119121 main <- (render' . vcat) <$>
120122 (mapM (elementToJATS opts' startLvl) elements)
src/Text/Pandoc/Writers/LaTeX.hs+10−7
@@ -42,6 +42,7 @@ import Data.Char (isAlphaNum, isAscii, isDigit, isLetter, isPunctuation, ord,
4242import Data.List (foldl', intercalate, intersperse, isInfixOf, nub, nubBy,
4343 stripPrefix, (\\))
4444import Data.Maybe (catMaybes, fromMaybe, isJust)
45+import Data.Text (Text)
4546import qualified Data.Text as T
4647import Network.URI (unEscapeString)
4748import Text.Pandoc.Class (PandocMonad, report)
@@ -114,13 +115,13 @@ startingState options = WriterState {
114115 , stEmptyLine = True }
115116
116117-- | Convert Pandoc to LaTeX.
117−writeLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> m String
118+writeLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> m Text
118119writeLaTeX options document =
119120 evalStateT (pandocToLaTeX options document) $
120121 startingState options
121122
122123-- | Convert Pandoc to LaTeX Beamer.
123−writeBeamer :: PandocMonad m => WriterOptions -> Pandoc -> m String
124+writeBeamer :: PandocMonad m => WriterOptions -> Pandoc -> m Text
124125writeBeamer options document =
125126 evalStateT (pandocToLaTeX options document) $
126127 (startingState options){ stBeamer = True }
@@ -128,7 +129,7 @@ writeBeamer options document =
128129type LW m = StateT WriterState m
129130
130131pandocToLaTeX :: PandocMonad m
131− => WriterOptions -> Pandoc -> LW m String
132+ => WriterOptions -> Pandoc -> LW m Text
132133pandocToLaTeX options (Pandoc meta blocks) = do
133134 -- Strip off final 'references' header if --natbib or --biblatex
134135 let method = writerCiteMethod options
@@ -146,9 +147,11 @@ pandocToLaTeX options (Pandoc meta blocks) = do
146147 let colwidth = if writerWrapText options == WrapAuto
147148 then Just $ writerColumns options
148149 else Nothing
150+ let render' :: Doc -> Text
151+ render' = render colwidth
149152 metadata <- metaToJSON options
150− (fmap (render colwidth) . blockListToLaTeX)
151− (fmap (render colwidth) . inlineListToLaTeX)
153+ (fmap render' . blockListToLaTeX)
154+ (fmap render' . inlineListToLaTeX)
152155 meta
153156 let bookClasses = ["memoir","book","report","scrreprt","scrbook"]
154157 let documentClass = case P.parse pDocumentClass "template" template of
@@ -180,8 +183,8 @@ pandocToLaTeX options (Pandoc meta blocks) = do
180183 then toSlides blocks''
181184 else return blocks''
182185 body <- mapM (elementToLaTeX options) $ hierarchicalize blocks'''
183− (biblioTitle :: String) <- liftM (render colwidth) $ inlineListToLaTeX lastHeader
184− let main = render colwidth $ vsep body
186+ (biblioTitle :: Text) <- render' <$> inlineListToLaTeX lastHeader
187+ let main = render' $ vsep body
185188 st <- get
186189 titleMeta <- stringToLaTeX TextString $ stringify $ docTitle meta
187190 authorsMeta <- mapM (stringToLaTeX TextString . stringify) $ docAuthors meta
src/Text/Pandoc/Writers/Man.hs+17−13
@@ -1,3 +1,4 @@
1+{-# LANGUAGE OverloadedStrings #-}
12{-
23Copyright (C) 2007-2017 John MacFarlane <jgm@berkeley.edu>
34
@@ -34,6 +35,8 @@ import Control.Monad.State
3435import Data.List (intercalate, intersperse, stripPrefix, sort)
3536import qualified Data.Map as Map
3637import Data.Maybe (fromMaybe)
38+import Data.Text (Text)
39+import qualified Data.Text as T
3740import Text.Pandoc.Builder (deleteMeta)
3841import Text.Pandoc.Class (PandocMonad, report)
3942import Text.Pandoc.Definition
@@ -62,36 +65,37 @@ defaultWriterState = WriterState { stNotes = []
6265 , stHasTables = False }
6366
6467-- | Convert Pandoc to Man.
65−writeMan :: PandocMonad m => WriterOptions -> Pandoc -> m String
68+writeMan :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6669writeMan opts document =
6770 evalStateT (pandocToMan opts document) defaultWriterState
6871
6972-- | Return groff man representation of document.
70−pandocToMan :: PandocMonad m => WriterOptions -> Pandoc -> StateT WriterState m String
73+pandocToMan :: PandocMonad m => WriterOptions -> Pandoc -> StateT WriterState m Text
7174pandocToMan opts (Pandoc meta blocks) = do
7275 let colwidth = if writerWrapText opts == WrapAuto
7376 then Just $ writerColumns opts
7477 else Nothing
75− let render' = render colwidth
78+ let render' :: Doc -> Text
79+ render' = render colwidth
7680 titleText <- inlineListToMan opts $ docTitle meta
7781 let title' = render' titleText
7882 let setFieldsFromTitle =
79− case break (== ' ') title' of
80− (cmdName, rest) -> case break (=='(') cmdName of
81− (xs, '(':ys) | not (null ys) &&
82− last ys == ')' ->
83+ case T.break (== ' ') title' of
84+ (cmdName, rest) -> case T.break (=='(') cmdName of
85+ (xs, ys) | "(" `T.isPrefixOf` ys
86+ && ")" `T.isSuffixOf` ys ->
8387 defField "title" xs .
84− defField "section" (init ys) .
85− case splitBy (=='|') rest of
88+ defField "section" (T.init $ T.drop 1 ys) .
89+ case T.splitOn "|" rest of
8690 (ft:hds) ->
87− defField "footer" (trim ft) .
91+ defField "footer" (T.strip ft) .
8892 defField "header"
89− (trim $ concat hds)
93+ (T.strip $ mconcat hds)
9094 [] -> id
9195 _ -> defField "title" title'
9296 metadata <- metaToJSON opts
93− (fmap (render colwidth) . blockListToMan opts)
94− (fmap (render colwidth) . inlineListToMan opts)
97+ (fmap render' . blockListToMan opts)
98+ (fmap render' . inlineListToMan opts)
9599 $ deleteMeta "title" meta
96100 body <- blockListToMan opts blocks
97101 notes <- gets stNotes
src/Text/Pandoc/Writers/Markdown.hs+13−10
@@ -45,6 +45,7 @@ import Data.Maybe (fromMaybe)
4545import Data.Monoid (Any (..))
4646import Data.Ord (comparing)
4747import qualified Data.Set as Set
48+import Data.Text (Text)
4849import qualified Data.Text as T
4950import qualified Data.Vector as V
5051import Data.Yaml (Value (Array, Bool, Number, Object, String))
@@ -106,7 +107,7 @@ instance Default WriterState
106107 }
107108
108109-- | Convert Pandoc to Markdown.
109−writeMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> m String
110+writeMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> m Text
110111writeMarkdown opts document =
111112 evalMD (pandocToMarkdown opts{
112113 writerWrapText = if isEnabled Ext_hard_line_breaks opts
@@ -116,7 +117,7 @@ writeMarkdown opts document =
116117
117118-- | Convert Pandoc to plain text (like markdown, but without links,
118119-- pictures, or inline formatting).
119−writePlain :: PandocMonad m => WriterOptions -> Pandoc -> m String
120+writePlain :: PandocMonad m => WriterOptions -> Pandoc -> m Text
120121writePlain opts document =
121122 evalMD (pandocToMarkdown opts document) def{ envPlain = True } def
122123
@@ -180,15 +181,17 @@ jsonToYaml (Number n) = text $ show n
180181jsonToYaml _ = empty
181182
182183-- | Return markdown representation of document.
183−pandocToMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> MD m String
184+pandocToMarkdown :: PandocMonad m => WriterOptions -> Pandoc -> MD m Text
184185pandocToMarkdown opts (Pandoc meta blocks) = do
185186 let colwidth = if writerWrapText opts == WrapAuto
186187 then Just $ writerColumns opts
187188 else Nothing
188189 isPlain <- asks envPlain
190+ let render' :: Doc -> Text
191+ render' = render colwidth . chomp
189192 metadata <- metaToJSON'
190− (fmap (render colwidth) . blockListToMarkdown opts)
191− (fmap (render colwidth) . blockToMarkdown opts . Plain)
193+ (fmap render' . blockListToMarkdown opts)
194+ (fmap render' . blockToMarkdown opts . Plain)
192195 meta
193196 let title' = maybe empty text $ getField "title" metadata
194197 let authors' = maybe [] (map text) $ getField "author" metadata
@@ -216,8 +219,6 @@ pandocToMarkdown opts (Pandoc meta blocks) = do
216219 else blocks
217220 body <- blockListToMarkdown opts blocks'
218221 notesAndRefs' <- notesAndRefs opts
219− let render' :: Doc -> String
220− render' = render colwidth . chomp
221222 let main = render' $ body <> notesAndRefs'
222223 let context = defField "toc" (render' toc)
223224 $ defField "body" main
@@ -571,7 +572,7 @@ blockToMarkdown' opts t@(Table caption aligns widths headers rows) = do
571572 gridTable opts blockListToMarkdown
572573 (all null headers) aligns' widths' headers rows
573574 | isEnabled Ext_raw_html opts -> fmap (id,) $
574− text <$>
575+ (text . T.unpack) <$>
575576 (writeHtml5String def $ Pandoc nullMeta [t])
576577 | otherwise -> return $ (id, text "[TABLE]")
577578 return $ nst $ tbl $$ caption'' $$ blankline
@@ -1110,7 +1111,8 @@ inlineToMarkdown opts lnk@(Link attr txt (src, tit))
11101111 | isEnabled Ext_raw_html opts &&
11111112 not (isEnabled Ext_link_attributes opts) &&
11121113 attr /= nullAttr = -- use raw HTML
1113− (text . trim) <$> writeHtml5String def (Pandoc nullMeta [Plain [lnk]])
1114+ (text . T.unpack . T.strip) <$>
1115+ writeHtml5String def (Pandoc nullMeta [Plain [lnk]])
11141116 | otherwise = do
11151117 plain <- asks envPlain
11161118 linktext <- inlineListToMarkdown opts txt
@@ -1149,7 +1151,8 @@ inlineToMarkdown opts img@(Image attr alternate (source, tit))
11491151 | isEnabled Ext_raw_html opts &&
11501152 not (isEnabled Ext_link_attributes opts) &&
11511153 attr /= nullAttr = -- use raw HTML
1152− (text . trim) <$> writeHtml5String def (Pandoc nullMeta [Plain [img]])
1154+ (text . T.unpack . T.strip) <$>
1155+ writeHtml5String def (Pandoc nullMeta [Plain [img]])
11531156 | otherwise = do
11541157 plain <- asks envPlain
11551158 let txt = if null alternate || alternate == [Str source]
src/Text/Pandoc/Writers/MediaWiki.hs+5−3
@@ -34,6 +34,7 @@ import Control.Monad.Reader
3434import Control.Monad.State
3535import Data.List (intercalate)
3636import qualified Data.Set as Set
37+import Data.Text (Text, pack)
3738import Text.Pandoc.Class (PandocMonad, report)
3839import Text.Pandoc.Logging
3940import Text.Pandoc.Definition
@@ -59,14 +60,14 @@ data WriterReader = WriterReader {
5960type MediaWikiWriter m = ReaderT WriterReader (StateT WriterState m)
6061
6162-- | Convert Pandoc to MediaWiki.
62−writeMediaWiki :: PandocMonad m => WriterOptions -> Pandoc -> m String
63+writeMediaWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6364writeMediaWiki opts document =
6465 let initialState = WriterState { stNotes = False, stOptions = opts }
6566 env = WriterReader { options = opts, listLevel = [], useTags = False }
6667 in evalStateT (runReaderT (pandocToMediaWiki document) env) initialState
6768
6869-- | Return MediaWiki representation of document.
69−pandocToMediaWiki :: PandocMonad m => Pandoc -> MediaWikiWriter m String
70+pandocToMediaWiki :: PandocMonad m => Pandoc -> MediaWikiWriter m Text
7071pandocToMediaWiki (Pandoc meta blocks) = do
7172 opts <- asks options
7273 metadata <- metaToJSON opts
@@ -81,7 +82,8 @@ pandocToMediaWiki (Pandoc meta blocks) = do
8182 let main = body ++ notes
8283 let context = defField "body" main
8384 $ defField "toc" (writerTableOfContents opts) metadata
84− return $ case writerTemplate opts of
85+ return $ pack
86+ $ case writerTemplate opts of
8587 Nothing -> main
8688 Just tpl -> renderTemplate' tpl context
8789
src/Text/Pandoc/Writers/Ms.hs+7−5
@@ -44,6 +44,7 @@ import Text.Pandoc.Options
4444import Text.Pandoc.Writers.Math
4545import Text.Printf ( printf )
4646import qualified Data.Text as T
47+import Data.Text (Text)
4748import qualified Data.Map as Map
4849import Data.Maybe ( catMaybes, fromMaybe )
4950import Data.List ( intersperse, intercalate, sort )
@@ -85,17 +86,18 @@ type Note = [Block]
8586type MS = StateT WriterState
8687
8788-- | Convert Pandoc to Ms.
88−writeMs :: PandocMonad m => WriterOptions -> Pandoc -> m String
89+writeMs :: PandocMonad m => WriterOptions -> Pandoc -> m Text
8990writeMs opts document =
9091 evalStateT (pandocToMs opts document) defaultWriterState
9192
9293-- | Return groff ms representation of document.
93−pandocToMs :: PandocMonad m => WriterOptions -> Pandoc -> MS m String
94+pandocToMs :: PandocMonad m => WriterOptions -> Pandoc -> MS m Text
9495pandocToMs opts (Pandoc meta blocks) = do
9596 let colwidth = if writerWrapText opts == WrapAuto
9697 then Just $ writerColumns opts
9798 else Nothing
98− let render' = render colwidth
99+ let render' :: Doc -> Text
100+ render' = render colwidth
99101 metadata <- metaToJSON opts
100102 (fmap render' . blockListToMs opts)
101103 (fmap render' . inlineListToMs' opts)
@@ -108,9 +110,9 @@ pandocToMs opts (Pandoc meta blocks) = do
108110 hasHighlighting <- gets stHighlighting
109111 let highlightingMacros = if hasHighlighting
110112 then case writerHighlightStyle opts of
111− Nothing -> ""
113+ Nothing -> mempty
112114 Just sty -> render' $ styleToMs sty
113− else ""
115+ else mempty
114116
115117 let context = defField "body" main
116118 $ defField "has-inline-math" hasInlineMath
src/Text/Pandoc/Writers/Muse.hs+7−4
@@ -43,6 +43,7 @@ even though it is supported only in Emacs Muse.
4343-}
4444module Text.Pandoc.Writers.Muse (writeMuse) where
4545import Control.Monad.State
46+import Data.Text (Text)
4647import Data.List (intersperse, transpose, isInfixOf)
4748import System.FilePath (takeExtension)
4849import Text.Pandoc.Class (PandocMonad)
@@ -68,7 +69,7 @@ data WriterState =
6869writeMuse :: PandocMonad m
6970 => WriterOptions
7071 -> Pandoc
71− -> m String
72+ -> m Text
7273writeMuse opts document =
7374 let st = WriterState { stNotes = []
7475 , stOptions = opts
@@ -81,15 +82,17 @@ writeMuse opts document =
8182-- | Return Muse representation of document.
8283pandocToMuse :: PandocMonad m
8384 => Pandoc
84− -> StateT WriterState m String
85+ -> StateT WriterState m Text
8586pandocToMuse (Pandoc meta blocks) = do
8687 opts <- gets stOptions
8788 let colwidth = if writerWrapText opts == WrapAuto
8889 then Just $ writerColumns opts
8990 else Nothing
91+ let render' :: Doc -> Text
92+ render' = render Nothing
9093 metadata <- metaToJSON opts
91− (fmap (render Nothing) . blockListToMuse)
92− (fmap (render Nothing) . inlineListToMuse)
94+ (fmap render' . blockListToMuse)
95+ (fmap render' . inlineListToMuse)
9396 meta
9497 body <- blockListToMuse blocks
9598 notes <- liftM (reverse . stNotes) get >>= notesToMuse
src/Text/Pandoc/Writers/Native.hs+2−1
@@ -30,6 +30,7 @@ Conversion of a 'Pandoc' document to a string representation.
3030-}
3131module Text.Pandoc.Writers.Native ( writeNative )
3232where
33+import Data.Text (Text)
3334import Data.List (intersperse)
3435import Text.Pandoc.Class (PandocMonad)
3536import Text.Pandoc.Definition
@@ -67,7 +68,7 @@ prettyBlock (Div attr blocks) =
6768prettyBlock block = text $ show block
6869
6970-- | Prettyprint Pandoc document.
70−writeNative :: PandocMonad m => WriterOptions -> Pandoc -> m String
71+writeNative :: PandocMonad m => WriterOptions -> Pandoc -> m Text
7172writeNative opts (Pandoc meta blocks) = return $
7273 let colwidth = if writerWrapText opts == WrapAuto
7374 then Just $ writerColumns opts
src/Text/Pandoc/Writers/ODT.hs+3−2
@@ -35,6 +35,7 @@ import Control.Monad.State
3535import qualified Data.ByteString.Lazy as B
3636import Data.List (isPrefixOf)
3737import Data.Maybe (fromMaybe)
38+import qualified Data.Text.Lazy as TL
3839import System.FilePath (takeDirectory, takeExtension, (<.>))
3940import Text.Pandoc.Class (PandocMonad, report)
4041import qualified Text.Pandoc.Class as P
@@ -45,7 +46,7 @@ import Text.Pandoc.MIME (extensionFromMimeType, getMimeType)
4546import Text.Pandoc.Options (WrapOption (..), WriterOptions (..))
4647import Text.Pandoc.Pretty
4748import Text.Pandoc.Shared (stringify)
48−import Text.Pandoc.UTF8 (fromStringLazy)
49+import Text.Pandoc.UTF8 (fromStringLazy, fromTextLazy)
4950import Text.Pandoc.Walk
5051import Text.Pandoc.Writers.OpenDocument (writeOpenDocument)
5152import Text.Pandoc.Writers.Shared (fixDisplayMath)
@@ -88,7 +89,7 @@ pandocToODT opts doc@(Pandoc meta _) = do
8889 newContents <- lift $ writeOpenDocument opts{writerWrapText = WrapNone} doc'
8990 epochtime <- floor `fmap` (lift P.getPOSIXTime)
9091 let contentEntry = toEntry "content.xml" epochtime
91− $ fromStringLazy newContents
92+ $ fromTextLazy $ TL.fromStrict newContents
9293 picEntries <- gets stEntries
9394 let archive = foldr addEntryToArchive refArchive
9495 $ contentEntry : picEntries
src/Text/Pandoc/Writers/OPML.hs+9−6
@@ -30,6 +30,8 @@ Conversion of 'Pandoc' documents to OPML XML.
3030-}
3131module Text.Pandoc.Writers.OPML ( writeOPML) where
3232import Control.Monad.Except (throwError)
33+import Data.Text (Text, unpack)
34+import qualified Data.Text as T
3335import qualified Text.Pandoc.Builder as B
3436import Text.Pandoc.Class (PandocMonad)
3537import Text.Pandoc.Compat.Time
@@ -45,7 +47,7 @@ import Text.Pandoc.Writers.Shared
4547import Text.Pandoc.XML
4648
4749-- | Convert Pandoc document to string in OPML format.
48−writeOPML :: PandocMonad m => WriterOptions -> Pandoc -> m String
50+writeOPML :: PandocMonad m => WriterOptions -> Pandoc -> m Text
4951writeOPML opts (Pandoc meta blocks) = do
5052 let elements = hierarchicalize blocks
5153 colwidth = if writerWrapText opts == WrapAuto
@@ -54,7 +56,7 @@ writeOPML opts (Pandoc meta blocks) = do
5456 meta' = B.setMeta "date" (B.str $ convertDate $ docDate meta) meta
5557 metadata <- metaToJSON opts
5658 (writeMarkdown def . Pandoc nullMeta)
57− (\ils -> trimr <$> (writeMarkdown def $ Pandoc nullMeta [Plain ils]))
59+ (\ils -> T.stripEnd <$> (writeMarkdown def $ Pandoc nullMeta [Plain ils]))
5860 meta'
5961 main <- (render colwidth . vcat) <$> (mapM (elementToOPML opts) elements)
6062 let context = defField "body" main metadata
@@ -63,9 +65,9 @@ writeOPML opts (Pandoc meta blocks) = do
6365 Just tpl -> renderTemplate' tpl context
6466
6567
66−writeHtmlInlines :: PandocMonad m => [Inline] -> m String
68+writeHtmlInlines :: PandocMonad m => [Inline] -> m Text
6769writeHtmlInlines ils =
68− trim <$> (writeHtml5String def $ Pandoc nullMeta [Plain ils])
70+ T.strip <$> (writeHtml5String def $ Pandoc nullMeta [Plain ils])
6971
7072-- date format: RFC 822: Thu, 14 Jul 2005 23:41:05 GMT
7173showDateTimeRFC822 :: UTCTime -> String
@@ -95,9 +97,10 @@ elementToOPML opts (Sec _ _num _ title elements) = do
9597 (blocks, rest) = span isBlk elements
9698 htmlIls <- writeHtmlInlines title
9799 md <- if null blocks
98− then return []
100+ then return mempty
99101 else do blks <- mapM fromBlk blocks
100102 writeMarkdown def $ Pandoc nullMeta blks
101− let attrs = [("text", htmlIls)] ++ [("_note", md) | not (null blocks)]
103+ let attrs = [("text", unpack htmlIls)] ++
104+ [("_note", unpack md) | not (null blocks)]
102105 o <- mapM (elementToOPML opts) rest
103106 return $ inTags True "outline" attrs $ vcat o
src/Text/Pandoc/Writers/OpenDocument.hs+6−4
@@ -36,6 +36,7 @@ import Control.Arrow ((***), (>>>))
3636import Control.Monad.State hiding (when)
3737import Data.Char (chr)
3838import Data.List (sortBy)
39+import Data.Text (Text)
3940import qualified Data.Map as Map
4041import Data.Ord (comparing)
4142import qualified Data.Set as Set
@@ -195,17 +196,18 @@ handleSpaces s
195196 rm [] = empty
196197
197198-- | Convert Pandoc document to string in OpenDocument format.
198−writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m String
199+writeOpenDocument :: PandocMonad m => WriterOptions -> Pandoc -> m Text
199200writeOpenDocument opts (Pandoc meta blocks) = do
200201 let colwidth = if writerWrapText opts == WrapAuto
201202 then Just $ writerColumns opts
202203 else Nothing
203− let render' = render colwidth
204+ let render' :: Doc -> Text
205+ render' = render colwidth
204206 ((body, metadata),s) <- flip runStateT
205207 defaultWriterState $ do
206208 m <- metaToJSON opts
207− (fmap (render colwidth) . blocksToOpenDocument opts)
208− (fmap (render colwidth) . inlinesToOpenDocument opts)
209+ (fmap render' . blocksToOpenDocument opts)
210+ (fmap render' . inlinesToOpenDocument opts)
209211 meta
210212 b <- render' `fmap` blocksToOpenDocument opts blocks
211213 return (b, m)
src/Text/Pandoc/Writers/Org.hs+7−4
@@ -37,6 +37,7 @@ Org-Mode: <http://orgmode.org>
3737module Text.Pandoc.Writers.Org (writeOrg) where
3838import Control.Monad.State
3939import Data.Char (isAlphaNum, toLower)
40+import Data.Text (Text)
4041import Data.List (intersect, intersperse, isPrefixOf, partition, transpose)
4142import Text.Pandoc.Class (PandocMonad, report)
4243import Text.Pandoc.Definition
@@ -56,7 +57,7 @@ data WriterState =
5657type Org = StateT WriterState
5758
5859-- | Convert Pandoc to Org.
59−writeOrg :: PandocMonad m => WriterOptions -> Pandoc -> m String
60+writeOrg :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6061writeOrg opts document = do
6162 let st = WriterState { stNotes = [],
6263 stHasMath = False,
@@ -64,15 +65,17 @@ writeOrg opts document = do
6465 evalStateT (pandocToOrg document) st
6566
6667-- | Return Org representation of document.
67−pandocToOrg :: PandocMonad m => Pandoc -> Org m String
68+pandocToOrg :: PandocMonad m => Pandoc -> Org m Text
6869pandocToOrg (Pandoc meta blocks) = do
6970 opts <- gets stOptions
7071 let colwidth = if writerWrapText opts == WrapAuto
7172 then Just $ writerColumns opts
7273 else Nothing
74+ let render' :: Doc -> Text
75+ render' = render colwidth
7376 metadata <- metaToJSON opts
74− (fmap (render colwidth) . blockListToOrg)
75− (fmap (render colwidth) . inlineListToOrg)
77+ (fmap render' . blockListToOrg)
78+ (fmap render' . inlineListToOrg)
7679 meta
7780 body <- blockListToOrg blocks
7881 notes <- gets (reverse . stNotes) >>= notesToOrg
src/Text/Pandoc/Writers/RST.hs+8−5
@@ -35,6 +35,7 @@ import Control.Monad.State
3535import Data.Char (isSpace, toLower)
3636import Data.List (isPrefixOf, stripPrefix)
3737import Data.Maybe (fromMaybe)
38+import Data.Text (Text, stripEnd)
3839import qualified Text.Pandoc.Builder as B
3940import Text.Pandoc.Class (PandocMonad, report)
4041import Text.Pandoc.Logging
@@ -62,7 +63,7 @@ data WriterState =
6263type RST = StateT WriterState
6364
6465-- | Convert Pandoc to RST.
65−writeRST :: PandocMonad m => WriterOptions -> Pandoc -> m String
66+writeRST :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6667writeRST opts document = do
6768 let st = WriterState { stNotes = [], stLinks = [],
6869 stImages = [], stHasMath = False,
@@ -71,19 +72,21 @@ writeRST opts document = do
7172 evalStateT (pandocToRST document) st
7273
7374-- | Return RST representation of document.
74−pandocToRST :: PandocMonad m => Pandoc -> RST m String
75+pandocToRST :: PandocMonad m => Pandoc -> RST m Text
7576pandocToRST (Pandoc meta blocks) = do
7677 opts <- gets stOptions
7778 let colwidth = if writerWrapText opts == WrapAuto
7879 then Just $ writerColumns opts
7980 else Nothing
81+ let render' :: Doc -> Text
82+ render' = render colwidth
8083 let subtit = case lookupMeta "subtitle" meta of
8184 Just (MetaBlocks [Plain xs]) -> xs
8285 _ -> []
8386 title <- titleToRST (docTitle meta) subtit
8487 metadata <- metaToJSON opts
85− (fmap (render colwidth) . blockListToRST)
86− (fmap (trimr . render colwidth) . inlineListToRST)
88+ (fmap render' . blockListToRST)
89+ (fmap (stripEnd . render') . inlineListToRST)
8790 $ B.deleteMeta "title" $ B.deleteMeta "subtitle" meta
8891 body <- blockListToRST' True $ case writerTemplate opts of
8992 Just _ -> normalizeHeadings 1 blocks
@@ -94,7 +97,7 @@ pandocToRST (Pandoc meta blocks) = do
9497 pics <- gets (reverse . stImages) >>= pictRefsToRST
9598 hasMath <- gets stHasMath
9699 rawTeX <- gets stHasRawTeX
97− let main = render colwidth $ foldl ($+$) empty $ [body, notes, refs, pics]
100+ let main = render' $ foldl ($+$) empty $ [body, notes, refs, pics]
98101 let context = defField "body" main
99102 $ defField "toc" (writerTableOfContents opts)
100103 $ defField "toc-depth" (show $ writerTOCDepth opts)
src/Text/Pandoc/Writers/RTF.hs+5−2
@@ -34,6 +34,8 @@ import Control.Monad.Except (catchError, throwError)
3434import qualified Data.ByteString as B
3535import Data.Char (chr, isDigit, ord)
3636import Data.List (intercalate, isSuffixOf)
37+import Data.Text (Text)
38+import qualified Data.Text as T
3739import qualified Data.Map as M
3840import Text.Pandoc.Class (PandocMonad, report)
3941import qualified Text.Pandoc.Class as P
@@ -97,7 +99,7 @@ rtfEmbedImage opts x@(Image attr _ (src,_)) = catchError
9799rtfEmbedImage _ x = return x
98100
99101-- | Convert Pandoc to a string in rich text format.
100−writeRTF :: PandocMonad m => WriterOptions -> Pandoc -> m String
102+writeRTF :: PandocMonad m => WriterOptions -> Pandoc -> m Text
101103writeRTF options doc = do
102104 -- handle images
103105 Pandoc meta@(Meta metamap) blocks <- walkM (rtfEmbedImage options) doc
@@ -123,7 +125,8 @@ writeRTF options doc = do
123125 then defField "toc" toc
124126 else id)
125127 $ metadata
126− return $ case writerTemplate options of
128+ return $ T.pack
129+ $ case writerTemplate options of
127130 Just tpl -> renderTemplate' tpl context
128131 Nothing -> case reverse body of
129132 ('\n':_) -> body
src/Text/Pandoc/Writers/TEI.hs+6−4
@@ -31,6 +31,7 @@ Conversion of 'Pandoc' documents to Docbook XML.
3131-}
3232module Text.Pandoc.Writers.TEI (writeTEI) where
3333import Data.Char (toLower)
34+import Data.Text (Text)
3435import Data.List (isPrefixOf, stripPrefix)
3536import qualified Text.Pandoc.Builder as B
3637import Text.Pandoc.Class (PandocMonad, report)
@@ -56,12 +57,13 @@ authorToTEI opts name' = do
5657 inTagsSimple "author" (text $ escapeStringForXML name)
5758
5859-- | Convert Pandoc document to string in Docbook format.
59−writeTEI :: PandocMonad m => WriterOptions -> Pandoc -> m String
60+writeTEI :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6061writeTEI opts (Pandoc meta blocks) = do
6162 let elements = hierarchicalize blocks
6263 colwidth = if writerWrapText opts == WrapAuto
6364 then Just $ writerColumns opts
6465 else Nothing
66+ render' :: Doc -> Text
6567 render' = render colwidth
6668 startLvl = case writerTopLevelDivision opts of
6769 TopLevelPart -> -1
@@ -71,9 +73,9 @@ writeTEI opts (Pandoc meta blocks) = do
7173 auths' <- mapM (authorToTEI opts) $ docAuthors meta
7274 let meta' = B.setMeta "author" auths' meta
7375 metadata <- metaToJSON opts
74− (fmap (render colwidth . vcat) .
75− (mapM (elementToTEI opts startLvl)) . hierarchicalize)
76− (fmap (render colwidth) . inlinesToTEI opts)
76+ (fmap (render' . vcat) .
77+ mapM (elementToTEI opts startLvl) . hierarchicalize)
78+ (fmap render' . inlinesToTEI opts)
7779 meta'
7880 main <- (render' . vcat) <$> mapM (elementToTEI opts startLvl) elements
7981 let context = defField "body" main
src/Text/Pandoc/Writers/Texinfo.hs+7−4
@@ -37,6 +37,7 @@ import Data.Char (chr, ord)
3737import Data.List (maximumBy, transpose)
3838import Data.Ord (comparing)
3939import qualified Data.Set as Set
40+import Data.Text (Text)
4041import Network.URI (unEscapeString)
4142import System.FilePath
4243import Text.Pandoc.Class (PandocMonad, report)
@@ -68,7 +69,7 @@ data WriterState =
6869type TI m = StateT WriterState m
6970
7071-- | Convert Pandoc to Texinfo.
71−writeTexinfo :: PandocMonad m => WriterOptions -> Pandoc -> m String
72+writeTexinfo :: PandocMonad m => WriterOptions -> Pandoc -> m Text
7273writeTexinfo options document =
7374 evalStateT (pandocToTexinfo options $ wrapTop document) $
7475 WriterState { stStrikeout = False, stSuperscript = False,
@@ -80,16 +81,18 @@ wrapTop :: Pandoc -> Pandoc
8081wrapTop (Pandoc meta blocks) =
8182 Pandoc meta (Header 0 nullAttr (docTitle meta) : blocks)
8283
83−pandocToTexinfo :: PandocMonad m => WriterOptions -> Pandoc -> TI m String
84+pandocToTexinfo :: PandocMonad m => WriterOptions -> Pandoc -> TI m Text
8485pandocToTexinfo options (Pandoc meta blocks) = do
8586 let titlePage = not $ all null
8687 $ docTitle meta : docDate meta : docAuthors meta
8788 let colwidth = if writerWrapText options == WrapAuto
8889 then Just $ writerColumns options
8990 else Nothing
91+ let render' :: Doc -> Text
92+ render' = render colwidth
9093 metadata <- metaToJSON options
91− (fmap (render colwidth) . blockListToTexinfo)
92− (fmap (render colwidth) . inlineListToTexinfo)
94+ (fmap render' . blockListToTexinfo)
95+ (fmap render' . inlineListToTexinfo)
9396 meta
9497 main <- blockListToTexinfo blocks
9598 st <- get
src/Text/Pandoc/Writers/Textile.hs+6−5
@@ -33,6 +33,7 @@ module Text.Pandoc.Writers.Textile ( writeTextile ) where
3333import Control.Monad.State
3434import Data.Char (isSpace)
3535import Data.List (intercalate)
36+import Data.Text (Text, pack)
3637import Text.Pandoc.Class (PandocMonad, report)
3738import Text.Pandoc.Logging
3839import Text.Pandoc.Definition
@@ -54,7 +55,7 @@ data WriterState = WriterState {
5455type TW = StateT WriterState
5556
5657-- | Convert Pandoc to Textile.
57−writeTextile :: PandocMonad m => WriterOptions -> Pandoc -> m String
58+writeTextile :: PandocMonad m => WriterOptions -> Pandoc -> m Text
5859writeTextile opts document =
5960 evalStateT (pandocToTextile opts document)
6061 WriterState { stNotes = [],
@@ -64,17 +65,17 @@ writeTextile opts document =
6465
6566-- | Return Textile representation of document.
6667pandocToTextile :: PandocMonad m
67− => WriterOptions -> Pandoc -> TW m String
68+ => WriterOptions -> Pandoc -> TW m Text
6869pandocToTextile opts (Pandoc meta blocks) = do
6970 metadata <- metaToJSON opts (blockListToTextile opts)
7071 (inlineListToTextile opts) meta
7172 body <- blockListToTextile opts blocks
7273 notes <- gets $ unlines . reverse . stNotes
73− let main = body ++ if null notes then "" else ("\n\n" ++ notes)
74+ let main = pack $ body ++ if null notes then "" else ("\n\n" ++ notes)
7475 let context = defField "body" main metadata
7576 case writerTemplate opts of
76− Nothing -> return main
77− Just tpl -> return $ renderTemplate' tpl context
77+ Nothing -> return main
78+ Just tpl -> return $ renderTemplate' tpl context
7879
7980withUseTags :: PandocMonad m => TW m a -> TW m a
8081withUseTags action = do
src/Text/Pandoc/Writers/ZimWiki.hs+4−4
@@ -37,7 +37,7 @@ import Control.Monad.State (StateT, evalStateT, gets, modify)
3737import Data.Default (Default (..))
3838import Data.List (intercalate, isInfixOf, isPrefixOf, transpose)
3939import qualified Data.Map as Map
40−import Data.Text (breakOnAll, pack)
40+import Data.Text (breakOnAll, pack, Text)
4141import Text.Pandoc.Class (PandocMonad, report)
4242import Text.Pandoc.Logging
4343import Text.Pandoc.Definition
@@ -61,17 +61,17 @@ instance Default WriterState where
6161type ZW = StateT WriterState
6262
6363-- | Convert Pandoc to ZimWiki.
64−writeZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> m String
64+writeZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> m Text
6565writeZimWiki opts document = evalStateT (pandocToZimWiki opts document) def
6666
6767-- | Return ZimWiki representation of document.
68−pandocToZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> ZW m String
68+pandocToZimWiki :: PandocMonad m => WriterOptions -> Pandoc -> ZW m Text
6969pandocToZimWiki opts (Pandoc meta blocks) = do
7070 metadata <- metaToJSON opts
7171 (fmap trimr . blockListToZimWiki opts)
7272 (inlineListToZimWiki opts)
7373 meta
74− body <- blockListToZimWiki opts blocks
74+ body <- pack <$> blockListToZimWiki opts blocks
7575 --let header = "Content-Type: text/x-zim-wiki\nWiki-Format: zim 0.4\n"
7676 let main = body
7777 let context = defField "body" main
src/Text/Pandoc/XML.hs+6−5
@@ -37,6 +37,8 @@ module Text.Pandoc.XML ( escapeCharForXML,
3737 fromEntities ) where
3838
3939import Data.Char (isAscii, isSpace, ord)
40+import Data.Text (Text)
41+import qualified Data.Text as T
4042import Text.HTML.TagSoup.Entity (lookupEntity)
4143import Text.Pandoc.Pretty
4244
@@ -91,11 +93,10 @@ inTagsIndented :: String -> Doc -> Doc
9193inTagsIndented tagType = inTags True tagType []
9294
9395-- | Escape all non-ascii characters using numerical entities.
94−toEntities :: String -> String
95−toEntities [] = ""
96−toEntities (c:cs)
97− | isAscii c = c : toEntities cs
98− | otherwise = "&#" ++ show (ord c) ++ ";" ++ toEntities cs
96+toEntities :: Text -> Text
97+toEntities = T.concatMap go
98+ where go c | isAscii c = T.singleton c
99+ | otherwise = T.pack ("&#" ++ show (ord c) ++ ";")
99100
100101-- Unescapes XML entities
101102fromEntities :: String -> String
test/Tests/Helpers.hs+4−3
@@ -106,17 +106,18 @@ class ToString a where
106106 toString :: a -> String
107107
108108instance ToString Pandoc where
109− toString d = purely (writeNative def{ writerTemplate = s }) $ toPandoc d
109+ toString d = unpack $
110+ purely (writeNative def{ writerTemplate = s }) $ toPandoc d
110111 where s = case d of
111112 (Pandoc (Meta m) _)
112113 | M.null m -> Nothing
113114 | otherwise -> Just "" -- need this to get meta output
114115
115116instance ToString Blocks where
116− toString = purely (writeNative def) . toPandoc
117+ toString = unpack . purely (writeNative def) . toPandoc
117118
118119instance ToString Inlines where
119− toString = trimr . purely (writeNative def) . toPandoc
120+ toString = trimr . unpack . purely (writeNative def) . toPandoc
120121
121122instance ToString String where
122123 toString = id
test/Tests/Readers/Docx.hs+2−1
@@ -3,6 +3,7 @@ module Tests.Readers.Docx (tests) where
33import Codec.Archive.Zip
44import qualified Data.ByteString.Lazy as B
55import qualified Data.ByteString as BS
6+import qualified Data.Text as T
67import qualified Data.Map as M
78import Test.Tasty
89import Test.Tasty.HUnit
@@ -27,7 +28,7 @@ defopts :: ReaderOptions
2728defopts = def{ readerExtensions = getDefaultExtensions "docx" }
2829
2930instance ToString NoNormPandoc where
30− toString d = purely (writeNative def{ writerTemplate = s }) $ toPandoc d
31+ toString d = T.unpack $ purely (writeNative def{ writerTemplate = s }) $ toPandoc d
3132 where s = case d of
3233 NoNormPandoc (Pandoc (Meta m) _)
3334 | M.null m -> Nothing
test/Tests/Readers/LaTeX.hs+1−1
@@ -6,7 +6,7 @@ import Tests.Helpers
66import Text.Pandoc
77import Text.Pandoc.Arbitrary ()
88import Text.Pandoc.Builder
9−import Data.Text (Text, pack)
9+import Data.Text (Text)
1010import qualified Data.Text as T
1111
1212latex :: Text -> Pandoc
test/Tests/Readers/Odt.hs+3−1
@@ -5,6 +5,7 @@ import qualified Data.ByteString.Lazy as B
55import qualified Data.ByteString as BS
66import qualified Text.Pandoc.UTF8 as UTF8
77import qualified Data.Map as M
8+import Data.Text (unpack)
89import Test.Tasty
910import Tests.Helpers
1011import Text.Pandoc
@@ -41,7 +42,8 @@ newtype NoNormPandoc = NoNormPandoc {unNoNorm :: Pandoc}
4142 deriving ( Show )
4243
4344instance ToString NoNormPandoc where
44− toString d = purely (writeNative def{ writerTemplate = s }) $ toPandoc d
45+ toString d = unpack $
46+ purely (writeNative def{ writerTemplate = s }) $ toPandoc d
4547 where s = case d of
4648 NoNormPandoc (Pandoc (Meta m) _)
4749 | M.null m -> Nothing
test/Tests/Writers/AsciiDoc.hs+2−1
@@ -1,5 +1,6 @@
11module Tests.Writers.AsciiDoc (tests) where
22
3+import Data.Text (unpack)
34import Test.Tasty
45import Tests.Helpers
56import Text.Pandoc
@@ -7,7 +8,7 @@ import Text.Pandoc.Arbitrary ()
78import Text.Pandoc.Builder
89
910asciidoc :: (ToPandoc a) => a -> String
10−asciidoc = purely (writeAsciiDoc def{ writerWrapText = WrapNone }) . toPandoc
11+asciidoc = unpack . purely (writeAsciiDoc def{ writerWrapText = WrapNone }) . toPandoc
1112
1213tests :: [TestTree]
1314tests = [ testGroup "emphasis"
test/Tests/Writers/ConTeXt.hs+3−2
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Tests.Writers.ConTeXt (tests) where
33
4+import Data.Text (unpack)
45import Test.Tasty
56import Test.Tasty.QuickCheck
67import Tests.Helpers
@@ -9,10 +10,10 @@ import Text.Pandoc.Arbitrary ()
910import Text.Pandoc.Builder
1011
1112context :: (ToPandoc a) => a -> String
12−context = purely (writeConTeXt def) . toPandoc
13+context = unpack . purely (writeConTeXt def) . toPandoc
1314
1415context' :: (ToPandoc a) => a -> String
15−context' = purely (writeConTeXt def{ writerWrapText = WrapNone }) . toPandoc
16+context' = unpack . purely (writeConTeXt def{ writerWrapText = WrapNone }) . toPandoc
1617
1718{-
1819 "my test" =: X =?> Y
test/Tests/Writers/Docbook.hs+2−1
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Tests.Writers.Docbook (tests) where
33
4+import Data.Text (unpack)
45import Test.Tasty
56import Tests.Helpers
67import Text.Pandoc
@@ -11,7 +12,7 @@ docbook :: (ToPandoc a) => a -> String
1112docbook = docbookWithOpts def{ writerWrapText = WrapNone }
1213
1314docbookWithOpts :: ToPandoc a => WriterOptions -> a -> String
14−docbookWithOpts opts = purely (writeDocbook4 opts) . toPandoc
15+docbookWithOpts opts = unpack . purely (writeDocbook4 opts) . toPandoc
1516
1617{-
1718 "my test" =: X =?> Y
test/Tests/Writers/HTML.hs+2−1
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Tests.Writers.HTML (tests) where
33
4+import Data.Text (unpack)
45import Test.Tasty
56import Tests.Helpers
67import Text.Pandoc
@@ -8,7 +9,7 @@ import Text.Pandoc.Arbitrary ()
89import Text.Pandoc.Builder
910
1011html :: (ToPandoc a) => a -> String
11−html = purely (writeHtml4String def{ writerWrapText = WrapNone }) . toPandoc
12+html = unpack . purely (writeHtml4String def{ writerWrapText = WrapNone }) . toPandoc
1213
1314{-
1415 "my test" =: X =?> Y
test/Tests/Writers/LaTeX.hs+3−2
@@ -1,6 +1,7 @@
11{-# LANGUAGE OverloadedStrings #-}
22module Tests.Writers.LaTeX (tests) where
33
4+import Data.Text (unpack)
45import Test.Tasty
56import Tests.Helpers
67import Text.Pandoc
@@ -14,10 +15,10 @@ latexListing :: (ToPandoc a) => a -> String
1415latexListing = latexWithOpts def{ writerListings = True }
1516
1617latexWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
17−latexWithOpts opts = purely (writeLaTeX opts) . toPandoc
18+latexWithOpts opts = unpack . purely (writeLaTeX opts) . toPandoc
1819
1920beamerWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
20−beamerWithOpts opts = purely (writeBeamer opts) . toPandoc
21+beamerWithOpts opts = unpack . purely (writeBeamer opts) . toPandoc
2122
2223{-
2324 "my test" =: X =?> Y
test/Tests/Writers/Markdown.hs+3−2
@@ -2,6 +2,7 @@
22{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
33module Tests.Writers.Markdown (tests) where
44
5+import Data.Text (unpack)
56import Test.Tasty
67import Tests.Helpers
78import Text.Pandoc
@@ -12,10 +13,10 @@ defopts :: WriterOptions
1213defopts = def{ writerExtensions = pandocExtensions }
1314
1415markdown :: (ToPandoc a) => a -> String
15−markdown = purely (writeMarkdown defopts) . toPandoc
16+markdown = unpack . purely (writeMarkdown defopts) . toPandoc
1617
1718markdownWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
18−markdownWithOpts opts x = purely (writeMarkdown opts) $ toPandoc x
19+markdownWithOpts opts x = unpack . purely (writeMarkdown opts) $ toPandoc x
1920
2021{-
2122 "my test" =: X =?> Y
test/Tests/Writers/Muse.hs+2−1
@@ -1,5 +1,6 @@
11module Tests.Writers.Muse (tests) where
22
3+import Data.Text (unpack)
34import Test.Tasty
45import Tests.Helpers
56import Text.Pandoc
@@ -10,7 +11,7 @@ muse :: (ToPandoc a) => a -> String
1011muse = museWithOpts def{ writerWrapText = WrapNone }
1112
1213museWithOpts :: (ToPandoc a) => WriterOptions -> a -> String
13−museWithOpts opts = purely (writeMuse opts) . toPandoc
14+museWithOpts opts = unpack . purely (writeMuse opts) . toPandoc
1415
1516infix 4 =:
1617(=:) :: (ToString a, ToPandoc a)
test/Tests/Writers/Native.hs+3−3
@@ -1,5 +1,6 @@
11module Tests.Writers.Native (tests) where
22
3+import Data.Text (unpack)
34import Test.Tasty
45import Test.Tasty.QuickCheck
56import Tests.Helpers
@@ -8,12 +9,11 @@ import Text.Pandoc.Arbitrary ()
89
910p_write_rt :: Pandoc -> Bool
1011p_write_rt d =
11− read (purely (writeNative def{ writerTemplate = Just "" }) d) == d
12+ read (unpack $ purely (writeNative def{ writerTemplate = Just "" }) d) == d
1213
1314p_write_blocks_rt :: [Block] -> Bool
1415p_write_blocks_rt bs =
15− read (purely (writeNative def) (Pandoc nullMeta bs)) ==
16− bs
16+ read (unpack $ purely (writeNative def) (Pandoc nullMeta bs)) == bs
1717
1818tests :: [TestTree]
1919tests = [ testProperty "p_write_rt" p_write_rt
trypandoc/trypandoc.hs+2−2
@@ -33,11 +33,11 @@ app req respond = do
3333 _ -> error $ "could not find reader for "
3434 ++ T.unpack fromFormat
3535 let writer = case getWriter (T.unpack toFormat) of
36− Right (StringWriter w) -> w writerOpts
36+ Right (TextWriter w) -> w writerOpts
3737 _ -> error $ "could not find writer for " ++
3838 T.unpack toFormat
3939 let result = case runPure $ reader (tabFilter 4 text) >>= writer of
40− Right s -> T.pack s
40+ Right s -> s
4141 Left err -> error (show err)
4242 let output = encode $ object [ T.pack "html" .= result
4343 , T.pack "name" .=