1{-# LANGUAGE FlexibleInstances   #-}
2{-# LANGUAGE GADTs               #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE OverloadedStrings   #-}
5{- |
6   Module      : Text.Pandoc
7   Copyright   : Copyright (C) 2006-2021 John MacFarlane
8   License     : GNU GPL, version 2 or above
9
10   Maintainer  : John MacFarlane <jgm@berkeley.edu>
11   Stability   : alpha
12   Portability : portable
13
14This helper module exports all writers functions.
15-}
16module Text.Pandoc.Writers
17  (
18    -- * Writers: converting /from/ Pandoc format
19      Writer(..)
20    , writers
21    , writeAsciiDoc
22    , writeAsciiDoctor
23    , writeBeamer
24    , writeBibTeX
25    , writeBibLaTeX
26    , writeCommonMark
27    , writeConTeXt
28    , writeCustom
29    , writeCslJson
30    , writeDZSlides
31    , writeDocbook4
32    , writeDocbook5
33    , writeDocx
34    , writeDokuWiki
35    , writeEPUB2
36    , writeEPUB3
37    , writeFB2
38    , writeIpynb
39    , writeHaddock
40    , writeHtml4
41    , writeHtml4String
42    , writeHtml5
43    , writeHtml5String
44    , writeICML
45    , writeJATS
46    , writeJatsArchiving
47    , writeJatsArticleAuthoring
48    , writeJatsPublishing
49    , writeJSON
50    , writeJira
51    , writeLaTeX
52    , writeMan
53    , writeMarkdown
54    , writeMediaWiki
55    , writeMs
56    , writeMuse
57    , writeNative
58    , writeODT
59    , writeOPML
60    , writeOpenDocument
61    , writeOrg
62    , writePlain
63    , writePowerpoint
64    , writeRST
65    , writeRTF
66    , writeRevealJs
67    , writeS5
68    , writeSlideous
69    , writeSlidy
70    , writeTEI
71    , writeTexinfo
72    , writeTextile
73    , writeXWiki
74    , writeZimWiki
75    , getWriter
76    ) where
77
78import Control.Monad.Except (throwError)
79import Control.Monad (unless)
80import Data.Aeson
81import qualified Data.ByteString.Lazy as BL
82import Data.Text (Text)
83import qualified Data.Text as T
84import Text.Pandoc.Class
85import Text.Pandoc.Definition
86import Text.Pandoc.Options
87import qualified Text.Pandoc.UTF8 as UTF8
88import Text.Pandoc.Error
89import Text.Pandoc.Writers.AsciiDoc
90import Text.Pandoc.Writers.BibTeX
91import Text.Pandoc.Writers.CommonMark
92import Text.Pandoc.Writers.ConTeXt
93import Text.Pandoc.Writers.CslJson
94import Text.Pandoc.Writers.Custom
95import Text.Pandoc.Writers.Docbook
96import Text.Pandoc.Writers.Docx
97import Text.Pandoc.Writers.DokuWiki
98import Text.Pandoc.Writers.EPUB
99import Text.Pandoc.Writers.FB2
100import Text.Pandoc.Writers.Ipynb
101import Text.Pandoc.Writers.Haddock
102import Text.Pandoc.Writers.HTML
103import Text.Pandoc.Writers.ICML
104import Text.Pandoc.Writers.JATS
105import Text.Pandoc.Writers.Jira
106import Text.Pandoc.Writers.LaTeX
107import Text.Pandoc.Writers.Man
108import Text.Pandoc.Writers.Markdown
109import Text.Pandoc.Writers.MediaWiki
110import Text.Pandoc.Writers.Ms
111import Text.Pandoc.Writers.Muse
112import Text.Pandoc.Writers.Native
113import Text.Pandoc.Writers.ODT
114import Text.Pandoc.Writers.OpenDocument
115import Text.Pandoc.Writers.OPML
116import Text.Pandoc.Writers.Org
117import Text.Pandoc.Writers.Powerpoint
118import Text.Pandoc.Writers.RST
119import Text.Pandoc.Writers.RTF
120import Text.Pandoc.Writers.TEI
121import Text.Pandoc.Writers.Texinfo
122import Text.Pandoc.Writers.Textile
123import Text.Pandoc.Writers.XWiki
124import Text.Pandoc.Writers.ZimWiki
125import Text.Parsec.Error
126
127data Writer m = TextWriter (WriterOptions -> Pandoc -> m Text)
128              | ByteStringWriter (WriterOptions -> Pandoc -> m BL.ByteString)
129
130-- | Association list of formats and writers.
131writers :: PandocMonad m => [ (Text, Writer m) ]
132writers = [
133   ("native"       , TextWriter writeNative)
134  ,("json"         , TextWriter writeJSON)
135  ,("docx"         , ByteStringWriter writeDocx)
136  ,("odt"          , ByteStringWriter writeODT)
137  ,("pptx"         , ByteStringWriter writePowerpoint)
138  ,("epub"         , ByteStringWriter writeEPUB3)
139  ,("epub2"        , ByteStringWriter writeEPUB2)
140  ,("epub3"        , ByteStringWriter writeEPUB3)
141  ,("fb2"          , TextWriter writeFB2)
142  ,("ipynb"        , TextWriter writeIpynb)
143  ,("html"         , TextWriter writeHtml5String)
144  ,("html4"        , TextWriter writeHtml4String)
145  ,("html5"        , TextWriter writeHtml5String)
146  ,("icml"         , TextWriter writeICML)
147  ,("s5"           , TextWriter writeS5)
148  ,("slidy"        , TextWriter writeSlidy)
149  ,("slideous"     , TextWriter writeSlideous)
150  ,("dzslides"     , TextWriter writeDZSlides)
151  ,("revealjs"     , TextWriter writeRevealJs)
152  ,("docbook"      , TextWriter writeDocbook5)
153  ,("docbook4"     , TextWriter writeDocbook4)
154  ,("docbook5"     , TextWriter writeDocbook5)
155  ,("jats"         , TextWriter writeJatsArchiving)
156  ,("jats_articleauthoring", TextWriter writeJatsArticleAuthoring)
157  ,("jats_publishing" , TextWriter writeJatsPublishing)
158  ,("jats_archiving" , TextWriter writeJatsArchiving)
159  ,("jira"         , TextWriter writeJira)
160  ,("opml"         , TextWriter writeOPML)
161  ,("opendocument" , TextWriter writeOpenDocument)
162  ,("latex"        , TextWriter writeLaTeX)
163  ,("beamer"       , TextWriter writeBeamer)
164  ,("context"      , TextWriter writeConTeXt)
165  ,("texinfo"      , TextWriter writeTexinfo)
166  ,("man"          , TextWriter writeMan)
167  ,("ms"           , TextWriter writeMs)
168  ,("markdown"     , TextWriter writeMarkdown)
169  ,("markdown_strict" , TextWriter writeMarkdown)
170  ,("markdown_phpextra" , TextWriter writeMarkdown)
171  ,("markdown_github" , TextWriter writeMarkdown)
172  ,("markdown_mmd" , TextWriter writeMarkdown)
173  ,("plain"        , TextWriter writePlain)
174  ,("rst"          , TextWriter writeRST)
175  ,("mediawiki"    , TextWriter writeMediaWiki)
176  ,("dokuwiki"     , TextWriter writeDokuWiki)
177  ,("xwiki"        , TextWriter writeXWiki)
178  ,("zimwiki"      , TextWriter writeZimWiki)
179  ,("textile"      , TextWriter writeTextile)
180  ,("rtf"          , TextWriter writeRTF)
181  ,("org"          , TextWriter writeOrg)
182  ,("asciidoc"     , TextWriter writeAsciiDoc)
183  ,("asciidoctor"  , TextWriter writeAsciiDoctor)
184  ,("haddock"      , TextWriter writeHaddock)
185  ,("commonmark"   , TextWriter writeCommonMark)
186  ,("commonmark_x" , TextWriter writeCommonMark)
187  ,("gfm"          , TextWriter writeCommonMark)
188  ,("tei"          , TextWriter writeTEI)
189  ,("muse"         , TextWriter writeMuse)
190  ,("csljson"      , TextWriter writeCslJson)
191  ,("bibtex"       , TextWriter writeBibTeX)
192  ,("biblatex"     , TextWriter writeBibLaTeX)
193  ]
194
195-- | Retrieve writer, extensions based on formatSpec (format+extensions).
196getWriter :: PandocMonad m => Text -> m (Writer m, Extensions)
197getWriter s =
198  case parseFormatSpec s of
199        Left e  -> throwError $ PandocAppError
200                    $ T.intercalate "\n" [T.pack m | Message m <- errorMessages e]
201        Right (writerName, extsToEnable, extsToDisable) ->
202           case lookup writerName writers of
203                   Nothing  -> throwError $
204                                 PandocUnknownWriterError writerName
205                   Just  w  -> do
206                     let allExts = getAllExtensions writerName
207                     let exts = foldr disableExtension
208                           (foldr enableExtension
209                             (getDefaultExtensions writerName)
210                                   extsToEnable) extsToDisable
211                     mapM_ (\ext ->
212                              unless (extensionEnabled ext allExts) $
213                                throwError $
214                                   PandocUnsupportedExtensionError
215                                   (T.drop 4 $ T.pack $ show ext) writerName)
216                          (extsToEnable ++ extsToDisable)
217                     return (w, exts)
218
219
220writeJSON :: PandocMonad m => WriterOptions -> Pandoc -> m Text
221writeJSON _ = return . UTF8.toText . BL.toStrict . encode
222