module Text.Pandoc
(
module Text.Pandoc.Definition
, module Text.Pandoc.Generic
, module Text.Pandoc.Options
, readers
, writers
, Reader (..)
, mkStringReader
, readMarkdown
, readLaTeX
, readHtml
, readNative
, readJSON
, Writer (..)
, writeNative
, writeJSON
, writeMarkdown
, writePlain
, writeLaTeX
, writeHtml
, writeHtmlString
, writeMan
, writeDocx
, writeHaddock
, writeCustom
, module Text.Pandoc.Templates
, pandocVersion
, getReader
, getWriter
, ToJsonFilter(..)
) where
import Text.Pandoc.Definition
import Text.Pandoc.Generic
import Text.Pandoc.JSON
import Text.Pandoc.Readers.Markdown
import Text.Pandoc.Readers.LaTeX
import Text.Pandoc.Readers.HTML
import Text.Pandoc.Readers.Native
import Text.Pandoc.Writers.Native
import Text.Pandoc.Writers.Markdown
import Text.Pandoc.Writers.LaTeX
import Text.Pandoc.Writers.HTML
import Text.Pandoc.Writers.Docx
import Text.Pandoc.Writers.Man
import Text.Pandoc.Writers.Haddock
import Text.Pandoc.Writers.Custom
import Text.Pandoc.Templates
import Text.Pandoc.Options
import Text.Pandoc.Shared (safeRead, warn)
import Text.Pandoc.MediaBag (MediaBag)
import Data.Aeson
import qualified Data.ByteString.Lazy as BL
import Data.List (intercalate)
import Data.Version (showVersion)
import Data.Set (Set)
import qualified Data.Set as Set
import Text.Parsec
import Text.Parsec.Error
import qualified Text.Pandoc.UTF8 as UTF8
import Paths_scholdoc (version)
pandocVersion :: String
pandocVersion = showVersion version
parseFormatSpec :: String
-> Either ParseError (String, Set Extension -> Set Extension)
parseFormatSpec = parse formatSpec ""
where formatSpec = do
name <- formatName
extMods <- many extMod
return (name, foldl (.) id extMods)
formatName = many1 $ noneOf "-+"
extMod = do
polarity <- oneOf "-+"
name <- many $ noneOf "-+"
ext <- case safeRead ("Ext_" ++ name) of
Just n -> return n
Nothing
| name == "lhs" -> return Ext_literate_haskell
| otherwise -> fail $ "Unknown extension: " ++ name
return $ case polarity of
'-' -> Set.delete ext
_ -> Set.insert ext
markdown :: ReaderOptions -> String -> IO Pandoc
markdown o s = do
let (doc, warnings) = readMarkdownWithWarnings o s
mapM_ warn warnings
return doc
data Reader = StringReader (ReaderOptions -> String -> IO Pandoc)
| ByteStringReader (ReaderOptions -> BL.ByteString -> IO (Pandoc, MediaBag))
mkStringReader :: (ReaderOptions -> String -> Pandoc) -> Reader
mkStringReader r = StringReader (\o s -> return $ r o s)
readers :: [(String, Reader)]
readers = [ ("native" , StringReader $ \_ s -> return $ readNative s)
,("json" , mkStringReader readJSON )
,("markdown" , StringReader markdown)
,("markdown_strict" , StringReader markdown)
,("markdown_phpextra" , StringReader markdown)
,("markdown_github" , StringReader markdown)
,("markdown_mmd", StringReader markdown)
,("markdown_scholarly", StringReader markdown)
]
data Writer = PureStringWriter (WriterOptions -> Pandoc -> String)
| IOStringWriter (WriterOptions -> Pandoc -> IO String)
| IOByteStringWriter (WriterOptions -> Pandoc -> IO BL.ByteString)
writers :: [ ( String, Writer ) ]
writers = [
("native" , PureStringWriter writeNative)
,("json" , PureStringWriter writeJSON)
,("docx" , IOByteStringWriter writeDocx)
,("html" , PureStringWriter writeHtmlString)
,("html5" , PureStringWriter $ \o ->
writeHtmlString o{ writerHtml5 = True })
,("s5" , PureStringWriter $ \o ->
writeHtmlString o{ writerSlideVariant = S5Slides
, writerTableOfContents = False })
,("slidy" , PureStringWriter $ \o ->
writeHtmlString o{ writerSlideVariant = SlidySlides })
,("slideous" , PureStringWriter $ \o ->
writeHtmlString o{ writerSlideVariant = SlideousSlides })
,("dzslides" , PureStringWriter $ \o ->
writeHtmlString o{ writerSlideVariant = DZSlides
, writerHtml5 = True })
,("revealjs" , PureStringWriter $ \o ->
writeHtmlString o{ writerSlideVariant = RevealJsSlides
, writerHtml5 = True })
,("latex" , PureStringWriter writeLaTeX)
,("beamer" , PureStringWriter $ \o ->
writeLaTeX o{ writerBeamer = True })
,("man" , PureStringWriter writeMan)
,("markdown" , PureStringWriter writeMarkdown)
,("markdown_strict" , PureStringWriter writeMarkdown)
,("markdown_phpextra" , PureStringWriter writeMarkdown)
,("markdown_github" , PureStringWriter writeMarkdown)
,("markdown_mmd" , PureStringWriter writeMarkdown)
,("markdown_scholarly" , PureStringWriter writeMarkdown)
,("plain" , PureStringWriter writePlain)
,("haddock" , PureStringWriter writeHaddock)
]
getDefaultExtensions :: String -> Set Extension
getDefaultExtensions "markdown_strict" = strictExtensions
getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
getDefaultExtensions "markdown_github" = githubMarkdownExtensions
getDefaultExtensions "markdown_scholarly" = scholarlyMarkdownExtensions
getDefaultExtensions "markdown" = pandocExtensions
getDefaultExtensions "plain" = pandocExtensions
getDefaultExtensions "html" = Set.fromList [Ext_auto_identifiers,
Ext_native_divs,
Ext_native_spans]
getDefaultExtensions "html5" = getDefaultExtensions "html"
getDefaultExtensions _ = Set.fromList [Ext_auto_identifiers]
getReader :: String -> Either String Reader
getReader s =
case parseFormatSpec s of
Left e -> Left $ intercalate "\n" $ [m | Message m <- errorMessages e]
Right (readerName, setExts) ->
case lookup readerName readers of
Nothing -> Left $ "Unknown reader: " ++ readerName
Just (StringReader r) -> Right $ StringReader $ \o ->
r o{ readerExtensions = setExts $
getDefaultExtensions readerName }
Just (ByteStringReader r) -> Right $ ByteStringReader $ \o ->
r o{ readerExtensions = setExts $
getDefaultExtensions readerName }
getWriter :: String -> Either String Writer
getWriter s
= case parseFormatSpec s of
Left e -> Left $ intercalate "\n" $ [m | Message m <- errorMessages e]
Right (writerName, setExts) ->
case lookup writerName writers of
Nothing -> Left $ "Unknown writer: " ++ writerName
Just (PureStringWriter r) -> Right $ PureStringWriter $
\o -> r o{ writerExtensions = setExts $
getDefaultExtensions writerName }
Just (IOStringWriter r) -> Right $ IOStringWriter $
\o -> r o{ writerExtensions = setExts $
getDefaultExtensions writerName }
Just (IOByteStringWriter r) -> Right $ IOByteStringWriter $
\o -> r o{ writerExtensions = setExts $
getDefaultExtensions writerName }
class ToJSONFilter a => ToJsonFilter a
where toJsonFilter :: a -> IO ()
toJsonFilter = toJSONFilter
readJSON :: ReaderOptions -> String -> Pandoc
readJSON _ = either error id . eitherDecode' . UTF8.fromStringLazy
writeJSON :: WriterOptions -> Pandoc -> String
writeJSON _ = UTF8.toStringLazy . encode