git.iko.soy/typeable/pandoc
on 4eff607 help sign in
388 lines 16 kB history raw
1{-# LANGUAGE ScopedTypeVariables, FlexibleInstances #-}
2{-
3Copyright (C) 2006-2016 John MacFarlane <jgm@berkeley.edu>
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation; either version 2 of the License, or
8(at your option) any later version.
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18-}
20{- |
21 Module : Text.Pandoc
22 Copyright : Copyright (C) 2006-2016 John MacFarlane
23 License : GNU GPL, version 2 or above
25 Maintainer : John MacFarlane <jgm@berkeley.edu>
26 Stability : alpha
27 Portability : portable
29This helper module exports the main writers, readers, and data
30structure definitions from the Pandoc libraries.
32A typical application will chain together a reader and a writer
33to convert strings from one format to another. For example, the
34following simple program will act as a filter converting markdown
35fragments to reStructuredText, using reference-style links instead of
36inline links:
38> module Main where
39> import Text.Pandoc
40> import Text.Pandoc.Error (handleError)
42> markdownToRST :: String -> String
43> markdownToRST = handleError .
44> writeRST def {writerReferenceLinks = True} .
45> readMarkdown def
47> main = getContents >>= putStrLn . markdownToRST
49Note: all of the readers assume that the input text has @'\n'@
50line endings. So if you get your input text from a web form,
51you should remove @'\r'@ characters using @filter (/='\r')@.
53-}
55module Text.Pandoc
56 (
57 -- * Definitions
58 module Text.Pandoc.Definition
59 -- * Generics
60 , module Text.Pandoc.Generic
61 -- * Options
62 , module Text.Pandoc.Options
63 -- * Lists of readers and writers
64 , readers
65 , writers
66 -- * Readers: converting /to/ Pandoc format
67 , Reader (..)
68 , mkStringReader
69 , readDocx
70 , readOdt
71 , readMarkdown
72 , readCommonMark
73 , readMediaWiki
74 , readRST
75 , readOrg
76 , readLaTeX
77 , readHtml
78 , readTextile
79 , readDocBook
80 , readOPML
81 , readHaddock
82 , readNative
83 , readJSON
84 , readTWiki
85 , readTxt2Tags
86 , readTxt2TagsNoMacros
87 , readEPUB
88 -- * Writers: converting /from/ Pandoc format
89 , Writer (..)
90 , writeNative
91 , writeJSON
92 , writeMarkdown
93 , writePlain
94 , writeRST
95 , writeLaTeX
96 , writeConTeXt
97 , writeTexinfo
98 , writeHtml
99 , writeHtmlString
100 , writeICML
101 , writeDocbook
102 , writeOPML
103 , writeOpenDocument
104 , writeMan
105 , writeMediaWiki
106 , writeDokuWiki
107 , writeZimWiki
108 , writeTextile
109 , writeRTF
110 , writeODT
111 , writeDocx
112 , writeEPUB
113 , writeFB2
114 , writeOrg
115 , writeAsciiDoc
116 , writeHaddock
117 , writeCommonMark
118 , writeCustom
119 , writeTEI
120 -- * Rendering templates and default templates
121 , module Text.Pandoc.Templates
122 -- * Miscellaneous
123 , getReader
124 , getWriter
125 , ToJsonFilter(..)
126 , pandocVersion
127 ) where
129import Text.Pandoc.Definition
130import Text.Pandoc.Generic
131import Text.Pandoc.JSON
132import Text.Pandoc.Readers.Markdown
133import Text.Pandoc.Readers.CommonMark
134import Text.Pandoc.Readers.MediaWiki
135import Text.Pandoc.Readers.RST
136import Text.Pandoc.Readers.Org
137import Text.Pandoc.Readers.DocBook
138import Text.Pandoc.Readers.OPML
139import Text.Pandoc.Readers.LaTeX
140import Text.Pandoc.Readers.HTML
141import Text.Pandoc.Readers.Textile
142import Text.Pandoc.Readers.Native
143import Text.Pandoc.Readers.Haddock
144import Text.Pandoc.Readers.TWiki
145import Text.Pandoc.Readers.Docx
146import Text.Pandoc.Readers.Odt
147import Text.Pandoc.Readers.Txt2Tags
148import Text.Pandoc.Readers.EPUB
149import Text.Pandoc.Writers.Native
150import Text.Pandoc.Writers.Markdown
151import Text.Pandoc.Writers.RST
152import Text.Pandoc.Writers.LaTeX
153import Text.Pandoc.Writers.ConTeXt
154import Text.Pandoc.Writers.Texinfo
155import Text.Pandoc.Writers.HTML
156import Text.Pandoc.Writers.ODT
157import Text.Pandoc.Writers.Docx
158import Text.Pandoc.Writers.EPUB
159import Text.Pandoc.Writers.FB2
160import Text.Pandoc.Writers.ICML
161import Text.Pandoc.Writers.Docbook
162import Text.Pandoc.Writers.OPML
163import Text.Pandoc.Writers.OpenDocument
164import Text.Pandoc.Writers.Man
165import Text.Pandoc.Writers.RTF
166import Text.Pandoc.Writers.MediaWiki
167import Text.Pandoc.Writers.DokuWiki
168import Text.Pandoc.Writers.ZimWiki
169import Text.Pandoc.Writers.Textile
170import Text.Pandoc.Writers.Org
171import Text.Pandoc.Writers.AsciiDoc
172import Text.Pandoc.Writers.Haddock
173import Text.Pandoc.Writers.CommonMark
174import Text.Pandoc.Writers.Custom
175import Text.Pandoc.Writers.TEI
176import Text.Pandoc.Templates
177import Text.Pandoc.Options
178import Text.Pandoc.Shared (safeRead, warn, mapLeft, pandocVersion)
179import Text.Pandoc.MediaBag (MediaBag)
180import Text.Pandoc.Error
181import Data.Aeson
182import qualified Data.ByteString.Lazy as BL
183import Data.List (intercalate)
184import Data.Set (Set)
185import qualified Data.Set as Set
186import Text.Parsec
187import Text.Parsec.Error
188import qualified Text.Pandoc.UTF8 as UTF8
190parseFormatSpec :: String
191 -> Either ParseError (String, Set Extension -> Set Extension)
192parseFormatSpec = parse formatSpec ""
193 where formatSpec = do
194 name <- formatName
195 extMods <- many extMod
196 return (name, \x -> foldl (flip ($)) x extMods)
197 formatName = many1 $ noneOf "-+"
198 extMod = do
199 polarity <- oneOf "-+"
200 name <- many $ noneOf "-+"
201 ext <- case safeRead ("Ext_" ++ name) of
202 Just n -> return n
203 Nothing
204 | name == "lhs" -> return Ext_literate_haskell
205 | otherwise -> fail $ "Unknown extension: " ++ name
206 return $ case polarity of
207 '-' -> Set.delete ext
208 _ -> Set.insert ext
211data Reader = StringReader (ReaderOptions -> String -> IO (Either PandocError Pandoc))
212 | ByteStringReader (ReaderOptions -> BL.ByteString -> IO (Either PandocError (Pandoc,MediaBag)))
214mkStringReader :: (ReaderOptions -> String -> Either PandocError Pandoc) -> Reader
215mkStringReader r = StringReader (\o s -> return $ r o s)
217mkStringReaderWithWarnings :: (ReaderOptions -> String -> Either PandocError (Pandoc, [String])) -> Reader
218mkStringReaderWithWarnings r = StringReader $ \o s ->
219 case r o s of
220 Left err -> return $ Left err
221 Right (doc, warnings) -> do
222 mapM_ warn warnings
223 return (Right doc)
225mkBSReader :: (ReaderOptions -> BL.ByteString -> Either PandocError (Pandoc, MediaBag)) -> Reader
226mkBSReader r = ByteStringReader (\o s -> return $ r o s)
228mkBSReaderWithWarnings :: (ReaderOptions -> BL.ByteString -> Either PandocError (Pandoc, MediaBag, [String])) -> Reader
229mkBSReaderWithWarnings r = ByteStringReader $ \o s ->
230 case r o s of
231 Left err -> return $ Left err
232 Right (doc, mediaBag, warnings) -> do
233 mapM_ warn warnings
234 return $ Right (doc, mediaBag)
236-- | Association list of formats and readers.
237readers :: [(String, Reader)]
238readers = [ ("native" , StringReader $ \_ s -> return $ readNative s)
239 ,("json" , mkStringReader readJSON )
240 ,("markdown" , mkStringReaderWithWarnings readMarkdownWithWarnings)
241 ,("markdown_strict" , mkStringReaderWithWarnings readMarkdownWithWarnings)
242 ,("markdown_phpextra" , mkStringReaderWithWarnings readMarkdownWithWarnings)
243 ,("markdown_github" , mkStringReaderWithWarnings readMarkdownWithWarnings)
244 ,("markdown_mmd", mkStringReaderWithWarnings readMarkdownWithWarnings)
245 ,("commonmark" , mkStringReader readCommonMark)
246 ,("rst" , mkStringReaderWithWarnings readRSTWithWarnings )
247 ,("mediawiki" , mkStringReader readMediaWiki)
248 ,("docbook" , mkStringReader readDocBook)
249 ,("opml" , mkStringReader readOPML)
250 ,("org" , mkStringReader readOrg)
251 ,("textile" , mkStringReader readTextile) -- TODO : textile+lhs
252 ,("html" , mkStringReader readHtml)
253 ,("latex" , mkStringReader readLaTeX)
254 ,("haddock" , mkStringReader readHaddock)
255 ,("twiki" , mkStringReader readTWiki)
256 ,("docx" , mkBSReaderWithWarnings readDocxWithWarnings)
257 ,("odt" , mkBSReader readOdt)
258 ,("t2t" , mkStringReader readTxt2TagsNoMacros)
259 ,("epub" , mkBSReader readEPUB)
260 ]
262data Writer = PureStringWriter (WriterOptions -> Pandoc -> String)
263 | IOStringWriter (WriterOptions -> Pandoc -> IO String)
264 | IOByteStringWriter (WriterOptions -> Pandoc -> IO BL.ByteString)
266-- | Association list of formats and writers.
267writers :: [ ( String, Writer ) ]
268writers = [
269 ("native" , PureStringWriter writeNative)
270 ,("json" , PureStringWriter writeJSON)
271 ,("docx" , IOByteStringWriter writeDocx)
272 ,("odt" , IOByteStringWriter writeODT)
273 ,("epub" , IOByteStringWriter $ \o ->
274 writeEPUB o{ writerEpubVersion = Just EPUB2 })
275 ,("epub3" , IOByteStringWriter $ \o ->
276 writeEPUB o{ writerEpubVersion = Just EPUB3 })
277 ,("fb2" , IOStringWriter writeFB2)
278 ,("html" , PureStringWriter writeHtmlString)
279 ,("html5" , PureStringWriter $ \o ->
280 writeHtmlString o{ writerHtml5 = True })
281 ,("icml" , IOStringWriter writeICML)
282 ,("s5" , PureStringWriter $ \o ->
283 writeHtmlString o{ writerSlideVariant = S5Slides
284 , writerTableOfContents = False })
285 ,("slidy" , PureStringWriter $ \o ->
286 writeHtmlString o{ writerSlideVariant = SlidySlides })
287 ,("slideous" , PureStringWriter $ \o ->
288 writeHtmlString o{ writerSlideVariant = SlideousSlides })
289 ,("dzslides" , PureStringWriter $ \o ->
290 writeHtmlString o{ writerSlideVariant = DZSlides
291 , writerHtml5 = True })
292 ,("revealjs" , PureStringWriter $ \o ->
293 writeHtmlString o{ writerSlideVariant = RevealJsSlides
294 , writerHtml5 = True })
295 ,("docbook" , PureStringWriter writeDocbook)
296 ,("docbook5" , PureStringWriter $ \o ->
297 writeDocbook o{ writerDocbook5 = True })
298 ,("opml" , PureStringWriter writeOPML)
299 ,("opendocument" , PureStringWriter writeOpenDocument)
300 ,("latex" , PureStringWriter writeLaTeX)
301 ,("beamer" , PureStringWriter $ \o ->
302 writeLaTeX o{ writerBeamer = True })
303 ,("context" , PureStringWriter writeConTeXt)
304 ,("texinfo" , PureStringWriter writeTexinfo)
305 ,("man" , PureStringWriter writeMan)
306 ,("markdown" , PureStringWriter writeMarkdown)
307 ,("markdown_strict" , PureStringWriter writeMarkdown)
308 ,("markdown_phpextra" , PureStringWriter writeMarkdown)
309 ,("markdown_github" , PureStringWriter writeMarkdown)
310 ,("markdown_mmd" , PureStringWriter writeMarkdown)
311 ,("plain" , PureStringWriter writePlain)
312 ,("rst" , PureStringWriter writeRST)
313 ,("mediawiki" , PureStringWriter writeMediaWiki)
314 ,("dokuwiki" , PureStringWriter writeDokuWiki)
315 ,("zimwiki" , PureStringWriter writeZimWiki)
316 ,("textile" , PureStringWriter writeTextile)
317 ,("rtf" , IOStringWriter writeRTFWithEmbeddedImages)
318 ,("org" , PureStringWriter writeOrg)
319 ,("asciidoc" , PureStringWriter writeAsciiDoc)
320 ,("haddock" , PureStringWriter writeHaddock)
321 ,("commonmark" , PureStringWriter writeCommonMark)
322 ,("tei" , PureStringWriter writeTEI)
323 ]
325getDefaultExtensions :: String -> Set Extension
326getDefaultExtensions "markdown_strict" = strictExtensions
327getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
328getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
329getDefaultExtensions "markdown_github" = githubMarkdownExtensions
330getDefaultExtensions "markdown" = pandocExtensions
331getDefaultExtensions "plain" = plainExtensions
332getDefaultExtensions "org" = Set.fromList [Ext_citations,
333 Ext_auto_identifiers]
334getDefaultExtensions "textile" = Set.fromList [Ext_auto_identifiers]
335getDefaultExtensions "html" = Set.fromList [Ext_auto_identifiers,
336 Ext_native_divs,
337 Ext_native_spans]
338getDefaultExtensions "html5" = getDefaultExtensions "html"
339getDefaultExtensions "epub" = Set.fromList [Ext_raw_html,
340 Ext_native_divs,
341 Ext_native_spans,
342 Ext_epub_html_exts]
343getDefaultExtensions _ = Set.fromList [Ext_auto_identifiers]
345-- | Retrieve reader based on formatSpec (format+extensions).
346getReader :: String -> Either String Reader
347getReader s =
348 case parseFormatSpec s of
349 Left e -> Left $ intercalate "\n" [m | Message m <- errorMessages e]
350 Right (readerName, setExts) ->
351 case lookup readerName readers of
352 Nothing -> Left $ "Unknown reader: " ++ readerName
353 Just (StringReader r) -> Right $ StringReader $ \o ->
354 r o{ readerExtensions = setExts $
355 getDefaultExtensions readerName }
356 Just (ByteStringReader r) -> Right $ ByteStringReader $ \o ->
357 r o{ readerExtensions = setExts $
358 getDefaultExtensions readerName }
360-- | Retrieve writer based on formatSpec (format+extensions).
361getWriter :: String -> Either String Writer
362getWriter s
363 = case parseFormatSpec s of
364 Left e -> Left $ intercalate "\n" [m | Message m <- errorMessages e]
365 Right (writerName, setExts) ->
366 case lookup writerName writers of
367 Nothing -> Left $ "Unknown writer: " ++ writerName
368 Just (PureStringWriter r) -> Right $ PureStringWriter $
369 \o -> r o{ writerExtensions = setExts $
370 getDefaultExtensions writerName }
371 Just (IOStringWriter r) -> Right $ IOStringWriter $
372 \o -> r o{ writerExtensions = setExts $
373 getDefaultExtensions writerName }
374 Just (IOByteStringWriter r) -> Right $ IOByteStringWriter $
375 \o -> r o{ writerExtensions = setExts $
376 getDefaultExtensions writerName }
378{-# DEPRECATED toJsonFilter "Use 'toJSONFilter' from 'Text.Pandoc.JSON' instead" #-}
379-- | Deprecated. Use @toJSONFilter@ from @Text.Pandoc.JSON@ instead.
380class ToJSONFilter a => ToJsonFilter a
381 where toJsonFilter :: a -> IO ()
382 toJsonFilter = toJSONFilter
384readJSON :: ReaderOptions -> String -> Either PandocError Pandoc
385readJSON _ = mapLeft ParseFailure . eitherDecode' . UTF8.fromStringLazy
387writeJSON :: WriterOptions -> Pandoc -> String
388writeJSON _ = UTF8.toStringLazy . encode