git.iko.soy/typeable/pandoc
on master help sign in
Raise error on unsupported extensions. Closes #4338.
746c92aJohn MacFarlane
MANUAL.txt+4−1
@@ -399,7 +399,7 @@ General options {.options}
399
399
400`--list-extensions`[`=`*FORMAT*]
400`--list-extensions`[`=`*FORMAT*]
401
401
402−: List supported extensions, one per line, preceded
402+: List supported extensions for *FORMAT*, one per line, preceded
403 by a `+` or `-` indicating whether it is enabled by default
403 by a `+` or `-` indicating whether it is enabled by default
404 in *FORMAT*. If *FORMAT* is not specified, defaults for
404 in *FORMAT*. If *FORMAT* is not specified, defaults for
405 pandoc's Markdown are given.
405 pandoc's Markdown are given.
@@ -1391,6 +1391,9 @@ Nonzero exit codes have the following meanings:
1391 4 PandocAppError
1391 4 PandocAppError
1392 5 PandocTemplateError
1392 5 PandocTemplateError
1393 6 PandocOptionError
1393 6 PandocOptionError
1394+ 21 PandocUnknownReaderError
1395+ 22 PandocUnknownWriterError
1396+ 23 PandocUnsupportedExtensionError
1394 31 PandocEpubSubdirectoryError
1397 31 PandocEpubSubdirectoryError
1395 43 PandocPDFError
1398 43 PandocPDFError
1396 47 PandocPDFProgramNotFoundError
1399 47 PandocPDFProgramNotFoundError
src/Text/Pandoc/App.hs+1−10
@@ -155,16 +155,7 @@ convertWithOpts opts = do
155 <> "` instead of `pandoc " <> inputFile <> " -o " <> outputFile <> "`."
155 <> "` instead of `pandoc " <> inputFile <> " -o " <> outputFile <> "`."
156 _ -> return ()
156 _ -> return ()
157
157
158− (reader, readerExts) <-
158+ (reader :: Reader PandocIO, readerExts) <- getReader readerName
159− case getReader readerName of
160− Right (r, es) -> return (r :: Reader PandocIO, es)
161− Left e -> throwError $ PandocAppError e'
162− where e' = case readerName of
163− "pdf" -> e ++
164− "\nPandoc can convert to PDF, but not from PDF."
165− "doc" -> e ++
166− "\nPandoc can convert from DOCX, but not from DOC.\nTry using Word to save your DOC file as DOCX, and convert that with pandoc."
167− _ -> e
168
159
169 let convertTabs = tabFilter (if optPreserveTabs opts ||
160 let convertTabs = tabFilter (if optPreserveTabs opts ||
170 readerName == "t2t" ||
161 readerName == "t2t" ||
src/Text/Pandoc/App/CommandLineOptions.hs+18−5
@@ -768,12 +768,25 @@ options =
768 , Option "" ["list-extensions"]
768 , Option "" ["list-extensions"]
769 (OptArg
769 (OptArg
770 (\arg _ -> do
770 (\arg _ -> do
771− let exts = getDefaultExtensions (fromMaybe "markdown" arg)
771+ let extList :: [Extension]
772+ extList = [minBound..maxBound]
773+ let allExts =
774+ case arg of
775+ Nothing -> extensionsFromList extList
776+ Just fmt -> getAllExtensions fmt
777+ let defExts =
778+ case arg of
779+ Nothing -> getDefaultExtensions
780+ "markdown"
781+ Just fmt -> getDefaultExtensions fmt
782+ let showExt x =
772− let showExt x = (if extensionEnabled x exts
783+ (if extensionEnabled x defExts
773− then '+'
784+ then '+'
785+ else if extensionEnabled x allExts
786+ then '-'
774− else '-') : drop 4 (show x)
787+ else ' ') : drop 4 (show x)
775 mapM_ (UTF8.hPutStrLn stdout . showExt)
788 mapM_ (UTF8.hPutStrLn stdout . showExt)
776− ([minBound..maxBound] :: [Extension])
789+ [ex | ex <- extList, extensionEnabled ex allExts]
777 exitSuccess )
790 exitSuccess )
778 "FORMAT")
791 "FORMAT")
779 ""
792 ""
src/Text/Pandoc/App/OutputSettings.hs+5−16
@@ -85,18 +85,12 @@ optToOutputSettings opts = do
85 then writerName
85 then writerName
86 else map toLower $ baseWriterName writerName
86 else map toLower $ baseWriterName writerName
87
87
88− (writer, writerExts) <-
88+ (writer :: Writer PandocIO, writerExts) <-
89 if ".lua" `isSuffixOf` format
89 if ".lua" `isSuffixOf` format
90 then return (TextWriter
90 then return (TextWriter
91 (\o d -> writeCustom writerName o d)
91 (\o d -> writeCustom writerName o d)
92 :: Writer PandocIO, mempty)
92 :: Writer PandocIO, mempty)
93− else case getWriter (map toLower writerName) of
93+ else getWriter (map toLower writerName)
94− Left e -> throwError $ PandocAppError $
95− if format == "pdf"
96− then e ++ "\n" ++ pdfIsNoWriterErrorMsg
97− else e
98− Right (w, es) -> return (w :: Writer PandocIO, es)
99−
100
94
101 let standalone = optStandalone opts || not (isTextFormat format) || pdfOutput
95 let standalone = optStandalone opts || not (isTextFormat format) || pdfOutput
102
96
@@ -249,13 +243,6 @@ optToOutputSettings opts = do
249baseWriterName :: String -> String
243baseWriterName :: String -> String
250baseWriterName = takeWhile (\c -> c /= '+' && c /= '-')
244baseWriterName = takeWhile (\c -> c /= '+' && c /= '-')
251
245
252−pdfIsNoWriterErrorMsg :: String
253−pdfIsNoWriterErrorMsg =
254− "To create a pdf using pandoc, use " ++
255− "-t latex|beamer|context|ms|html5" ++
256− "\nand specify an output file with " ++
257− ".pdf extension (-o filename.pdf)."
258−
259pdfWriterAndProg :: Maybe String -- ^ user-specified writer name
246pdfWriterAndProg :: Maybe String -- ^ user-specified writer name
260 -> Maybe String -- ^ user-specified pdf-engine
247 -> Maybe String -- ^ user-specified pdf-engine
261 -> IO (String, Maybe String) -- ^ IO (writerName, maybePdfEngineProg)
248 -> IO (String, Maybe String) -- ^ IO (writerName, maybePdfEngineProg)
@@ -263,6 +250,8 @@ pdfWriterAndProg mWriter mEngine = do
263 let panErr msg = liftIO $ E.throwIO $ PandocAppError msg
250 let panErr msg = liftIO $ E.throwIO $ PandocAppError msg
264 case go mWriter mEngine of
251 case go mWriter mEngine of
265 Right (writ, prog) -> return (writ, Just prog)
252 Right (writ, prog) -> return (writ, Just prog)
253+ Left "pdf writer" -> liftIO $ E.throwIO $
254+ PandocUnknownWriterError "pdf"
266 Left err -> panErr err
255 Left err -> panErr err
267 where
256 where
268 go Nothing Nothing = Right ("latex", "pdflatex")
257 go Nothing Nothing = Right ("latex", "pdflatex")
@@ -279,7 +268,7 @@ pdfWriterAndProg mWriter mEngine = do
279 [] -> Left $
268 [] -> Left $
280 "pdf-engine " ++ eng ++ " not known"
269 "pdf-engine " ++ eng ++ " not known"
281
270
282− engineForWriter "pdf" = Left pdfIsNoWriterErrorMsg
271+ engineForWriter "pdf" = Left "pdf writer"
283 engineForWriter w = case [e | (f,e) <- engines, f == baseWriterName w] of
272 engineForWriter w = case [e | (f,e) <- engines, f == baseWriterName w] of
284 eng : _ -> Right eng
273 eng : _ -> Right eng
285 [] -> Left $
274 [] -> Left $
src/Text/Pandoc/Error.hs+23
@@ -54,6 +54,9 @@ data PandocError = PandocIOError String IOError
54 | PandocMacroLoop String
54 | PandocMacroLoop String
55 | PandocUTF8DecodingError String Int Word8
55 | PandocUTF8DecodingError String Int Word8
56 | PandocIpynbDecodingError String
56 | PandocIpynbDecodingError String
57+ | PandocUnknownReaderError String
58+ | PandocUnknownWriterError String
59+ | PandocUnsupportedExtensionError String String
57 deriving (Show, Typeable, Generic)
60 deriving (Show, Typeable, Generic)
58
61
59instance Exception PandocError
62instance Exception PandocError
@@ -112,6 +115,26 @@ handleError (Left e) =
112 "The input must be a UTF-8 encoded text."
115 "The input must be a UTF-8 encoded text."
113 PandocIpynbDecodingError w -> err 93 $
116 PandocIpynbDecodingError w -> err 93 $
114 "ipynb decoding error: " ++ w
117 "ipynb decoding error: " ++ w
118+ PandocUnknownReaderError r -> err 21 $
119+ "Unknown input format " ++ r ++
120+ case r of
121+ "doc" -> "\nPandoc can convert from DOCX, but not from DOC." ++
122+ "\nTry using Word to save your DOC file as DOCX," ++
123+ " and convert that with pandoc."
124+ "pdf" -> "\nPandoc can convert to PDF, but not from PDF."
125+ _ -> ""
126+ PandocUnknownWriterError w -> err 22 $
127+ "Unknown output format " ++ w ++
128+ case w of
129+ "pdf" -> "To create a pdf using pandoc, use" ++
130+ " -t latex|beamer|context|ms|html5" ++
131+ "\nand specify an output file with " ++
132+ ".pdf extension (-o filename.pdf)."
133+ "doc" -> "\nPandoc can convert to DOCX, but not from DOC."
134+ _ -> ""
135+ PandocUnsupportedExtensionError ext f -> err 23 $
136+ "The extension " ++ ext ++ " is not supported " ++
137+ "for " ++ f
115
138
116err :: Int -> String -> IO a
139err :: Int -> String -> IO a
117err exitCode msg = do
140err exitCode msg = do
src/Text/Pandoc/Extensions.hs+151−15
@@ -26,6 +26,7 @@ module Text.Pandoc.Extensions ( Extension(..)
26 , enableExtension
26 , enableExtension
27 , disableExtension
27 , disableExtension
28 , getDefaultExtensions
28 , getDefaultExtensions
29+ , getAllExtensions
29 , pandocExtensions
30 , pandocExtensions
30 , plainExtensions
31 , plainExtensions
31 , strictExtensions
32 , strictExtensions
@@ -312,12 +313,12 @@ strictExtensions = extensionsFromList
312
313
313-- | Default extensions from format-describing string.
314-- | Default extensions from format-describing string.
314getDefaultExtensions :: String -> Extensions
315getDefaultExtensions :: String -> Extensions
315−getDefaultExtensions "markdown_strict" = strictExtensions
316+getDefaultExtensions "markdown_strict" = strictExtensions
316getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
317getDefaultExtensions "markdown_phpextra" = phpMarkdownExtraExtensions
317−getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
318+getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
318−getDefaultExtensions "markdown_github" = githubMarkdownExtensions
319+getDefaultExtensions "markdown_github" = githubMarkdownExtensions
319−getDefaultExtensions "markdown" = pandocExtensions
320+getDefaultExtensions "markdown" = pandocExtensions
320−getDefaultExtensions "ipynb" =
321+getDefaultExtensions "ipynb" =
321 extensionsFromList
322 extensionsFromList
322 [ Ext_all_symbols_escapable
323 [ Ext_all_symbols_escapable
323 , Ext_pipe_tables
324 , Ext_pipe_tables
@@ -379,16 +380,149 @@ getDefaultExtensions "opml" = pandocExtensions -- affects notes
379getDefaultExtensions _ = extensionsFromList
380getDefaultExtensions _ = extensionsFromList
380 [Ext_auto_identifiers]
381 [Ext_auto_identifiers]
381
382
383+allMarkdownExtensions :: Extensions
384+allMarkdownExtensions =
385+ pandocExtensions <>
386+ extensionsFromList
387+ [ Ext_old_dashes
388+ , Ext_angle_brackets_escapable
389+ , Ext_lists_without_preceding_blankline
390+ , Ext_four_space_rule
391+ , Ext_spaced_reference_links
392+ , Ext_hard_line_breaks
393+ , Ext_ignore_line_breaks
394+ , Ext_east_asian_line_breaks
395+ , Ext_emoji
396+ , Ext_tex_math_single_backslash
397+ , Ext_tex_math_double_backslash
398+ , Ext_markdown_attribute
399+ , Ext_mmd_title_block
400+ , Ext_abbreviations
401+ , Ext_autolink_bare_uris
402+ , Ext_mmd_link_attributes
403+ , Ext_mmd_header_identifiers
404+ , Ext_compact_definition_lists
405+ , Ext_gutenberg
406+ , Ext_smart
407+ , Ext_literate_haskell
408+ ]
409+
410+
411+-- | Get all valid extensions for a format. This is used
412+-- mainly in checking format specifications for validity.
413+getAllExtensions :: String -> Extensions
414+getAllExtensions f = universalExtensions <> getAll f
415+ where
416+ autoIdExtensions = extensionsFromList
417+ [ Ext_auto_identifiers
418+ , Ext_gfm_auto_identifiers
419+ , Ext_ascii_identifiers
420+ ]
421+ universalExtensions = extensionsFromList
422+ [ Ext_east_asian_line_breaks ]
423+ getAll "markdown_strict" = allMarkdownExtensions
424+ getAll "markdown_phpextra" = allMarkdownExtensions
425+ getAll "markdown_mmd" = allMarkdownExtensions
426+ getAll "markdown_github" = allMarkdownExtensions
427+ getAll "markdown" = allMarkdownExtensions
428+ getAll "ipynb" = allMarkdownExtensions
429+ getAll "docx" = extensionsFromList
430+ [ Ext_empty_paragraphs
431+ , Ext_styles
432+ ]
433+ getAll "opendocument" = extensionsFromList
434+ [ Ext_empty_paragraphs
435+ , Ext_native_numbering
436+ ]
437+ getAll "odt" = getAll "opendocument" <> autoIdExtensions
438+ getAll "muse" = autoIdExtensions <>
439+ extensionsFromList
440+ [ Ext_amuse ]
441+ getAll "asciidoc" = autoIdExtensions
442+ getAll "plain" = allMarkdownExtensions
443+ getAll "gfm" = githubMarkdownExtensions <>
444+ autoIdExtensions <>
445+ extensionsFromList
446+ [ Ext_raw_html
447+ , Ext_raw_tex -- only supported in writer (for math)
448+ , Ext_hard_line_breaks
449+ , Ext_smart
450+ ]
451+ getAll "commonmark" = getAll "gfm"
452+ getAll "org" = autoIdExtensions <>
453+ extensionsFromList
454+ [ Ext_citations
455+ , Ext_smart
456+ ]
457+ getAll "html" = autoIdExtensions <>
458+ extensionsFromList
459+ [ Ext_native_divs
460+ , Ext_line_blocks
461+ , Ext_native_spans
462+ , Ext_empty_paragraphs
463+ , Ext_raw_html
464+ , Ext_raw_tex
465+ , Ext_task_lists
466+ , Ext_tex_math_dollars
467+ , Ext_tex_math_single_backslash
468+ , Ext_tex_math_double_backslash
469+ , Ext_literate_haskell
470+ , Ext_epub_html_exts
471+ ]
472+ getAll "html4" = getAll "html"
473+ getAll "html5" = getAll "html"
474+ getAll "epub" = getAll "html"
475+ getAll "epub2" = getAll "epub"
476+ getAll "epub3" = getAll "epub"
477+ getAll "latex" = autoIdExtensions <>
478+ extensionsFromList
479+ [ Ext_smart
480+ , Ext_latex_macros
481+ , Ext_raw_tex
482+ , Ext_task_lists
483+ , Ext_literate_haskell
484+ ]
485+ getAll "beamer" = getAll "latex"
486+ getAll "context" = autoIdExtensions <>
487+ extensionsFromList
488+ [ Ext_smart
489+ , Ext_raw_tex
490+ , Ext_ntb
491+ ]
492+ getAll "textile" = autoIdExtensions <>
493+ extensionsFromList
494+ [ Ext_old_dashes
495+ , Ext_smart
496+ , Ext_raw_tex
497+ ]
498+ getAll "opml" = allMarkdownExtensions -- affects notes
499+ getAll "twiki" = autoIdExtensions <>
500+ extensionsFromList
501+ [ Ext_smart ]
502+ getAll "vimwiki" = autoIdExtensions
503+ getAll "dokuwiki" = autoIdExtensions
504+ getAll "tikiwiki" = autoIdExtensions
505+ getAll "rst" = autoIdExtensions <>
506+ extensionsFromList
507+ [ Ext_smart
508+ , Ext_literate_haskell
509+ ]
510+ getAll "mediawiki" = autoIdExtensions <>
511+ extensionsFromList
512+ [ Ext_smart ]
513+ getAll _ = mempty
514+
515+
382−-- | Parse a format-specifying string into a markup format and a function that
516+-- | Parse a format-specifying string into a markup format,
383−-- takes Extensions and enables and disables extensions as defined in the format
517+-- a set of extensions to enable, and a set of extensions to disable.
384−-- spec.
385parseFormatSpec :: String
518parseFormatSpec :: String
386− -> Either ParseError (String, Extensions -> Extensions)
519+ -> Either ParseError (String, [Extension], [Extension])
387parseFormatSpec = parse formatSpec ""
520parseFormatSpec = parse formatSpec ""
388 where formatSpec = do
521 where formatSpec = do
389 name <- formatName
522 name <- formatName
523+ (extsToEnable, extsToDisable) <- foldl (flip ($)) ([],[]) <$>
390− extMods <- many extMod
524+ many extMod
391− return (name, \x -> foldl (flip ($)) x extMods)
525+ return (name, reverse extsToEnable, reverse extsToDisable)
392 formatName = many1 $ noneOf "-+"
526 formatName = many1 $ noneOf "-+"
393 extMod = do
527 extMod = do
394 polarity <- oneOf "-+"
528 polarity <- oneOf "-+"
@@ -397,10 +531,12 @@ parseFormatSpec = parse formatSpec ""
397 Just n -> return n
531 Just n -> return n
398 Nothing
532 Nothing
399 | name == "lhs" -> return Ext_literate_haskell
533 | name == "lhs" -> return Ext_literate_haskell
400− | otherwise -> Prelude.fail $ "Unknown extension: " ++ name
534+ | otherwise -> Prelude.fail $
535+ "Unknown extension: " ++ name
536+ return $ \(extsToEnable, extsToDisable) ->
401− return $ case polarity of
537+ case polarity of
402− '-' -> disableExtension ext
538+ '+' -> (ext : extsToEnable, extsToDisable)
403− _ -> enableExtension ext
539+ _ -> (extsToEnable, ext : extsToDisable)
404
540
405#ifdef DERIVE_JSON_VIA_TH
541#ifdef DERIVE_JSON_VIA_TH
406$(deriveJSON defaultOptions ''Extension)
542$(deriveJSON defaultOptions ''Extension)
src/Text/Pandoc/Lua/Module/Pandoc.hs+15−10
@@ -16,6 +16,7 @@ module Text.Pandoc.Lua.Module.Pandoc
16
16
17import Prelude
17import Prelude
18import Control.Monad (when)
18import Control.Monad (when)
19+import Control.Monad.Except (throwError)
19import Data.Default (Default (..))
20import Data.Default (Default (..))
20import Data.Maybe (fromMaybe)
21import Data.Maybe (fromMaybe)
21import Data.Text (pack)
22import Data.Text (pack)
@@ -34,6 +35,7 @@ import qualified Data.ByteString.Lazy as BL
34import qualified Data.ByteString.Lazy.Char8 as BSL
35import qualified Data.ByteString.Lazy.Char8 as BSL
35import qualified Foreign.Lua as Lua
36import qualified Foreign.Lua as Lua
36import qualified Text.Pandoc.Lua.Util as LuaUtil
37import qualified Text.Pandoc.Lua.Util as LuaUtil
38+import Text.Pandoc.Error
37
39
38-- | Push the "pandoc" on the lua stack. Requires the `list` module to be
40-- | Push the "pandoc" on the lua stack. Requires the `list` module to be
39-- loaded.
41-- loaded.
@@ -60,17 +62,20 @@ walkBlock = walkElement
60readDoc :: String -> Optional String -> Lua NumResults
62readDoc :: String -> Optional String -> Lua NumResults
61readDoc content formatSpecOrNil = do
63readDoc content formatSpecOrNil = do
62 let formatSpec = fromMaybe "markdown" (Lua.fromOptional formatSpecOrNil)
64 let formatSpec = fromMaybe "markdown" (Lua.fromOptional formatSpecOrNil)
65+ res <- Lua.liftIO . runIO $
63− case getReader formatSpec of
66+ getReader formatSpec >>= \(rdr,es) ->
64− Left s -> Lua.raiseError s -- Unknown reader
65− Right (reader, es) ->
66− case reader of
67+ case rdr of
67− TextReader r -> do
68+ TextReader r ->
68− res <- Lua.liftIO . runIO $
69 r def{ readerExtensions = es } (pack content)
69 r def{ readerExtensions = es } (pack content)
70+ _ -> throwError $ PandocSomeError $
71+ "Only textual formats are supported"
70− case res of
72+ case res of
71− Right pd -> (1 :: NumResults) <$ Lua.push pd -- success, push Pandoc
73+ Right pd -> (1 :: NumResults) <$ Lua.push pd -- success, push Pandoc
72− Left s -> Lua.raiseError (show s) -- error while reading
74+ Left (PandocUnknownReaderError f) -> Lua.raiseError $
73− _ -> Lua.raiseError "Only string formats are supported at the moment."
75+ "Unknown reader: " ++ f
76+ Left (PandocUnsupportedExtensionError e f) -> Lua.raiseError $
77+ "Extension " ++ e ++ " not supported for " ++ f
78+ Left e -> Lua.raiseError $ show e
74
79
75-- | Pipes input through a command.
80-- | Pipes input through a command.
76pipeFn :: String
81pipeFn :: String
src/Text/Pandoc/Readers.hs+20−6
@@ -55,6 +55,7 @@ module Text.Pandoc.Readers
55 ) where
55 ) where
56
56
57import Prelude
57import Prelude
58+import Control.Monad (unless)
58import Control.Monad.Except (throwError)
59import Control.Monad.Except (throwError)
59import Data.Aeson
60import Data.Aeson
60import qualified Data.ByteString.Lazy as BL
61import qualified Data.ByteString.Lazy as BL
@@ -134,15 +135,28 @@ readers = [ ("native" , TextReader readNative)
134 ]
135 ]
135
136
136-- | Retrieve reader, extensions based on formatSpec (format+extensions).
137-- | Retrieve reader, extensions based on formatSpec (format+extensions).
137−getReader :: PandocMonad m => String -> Either String (Reader m, Extensions)
138+getReader :: PandocMonad m => String -> m (Reader m, Extensions)
138getReader s =
139getReader s =
139 case parseFormatSpec s of
140 case parseFormatSpec s of
141+ Left e -> throwError $ PandocAppError
140− Left e -> Left $ intercalate "\n" [m | Message m <- errorMessages e]
142+ $ intercalate "\n" [m | Message m <- errorMessages e]
141− Right (readerName, setExts) ->
143+ Right (readerName, extsToEnable, extsToDisable) ->
142 case lookup readerName readers of
144 case lookup readerName readers of
145+ Nothing -> throwError $ PandocUnknownReaderError
143− Nothing -> Left $ "Unknown reader: " ++ readerName
146+ readerName
144− Just r -> Right (r, setExts $
147+ Just r -> do
148+ let allExts = getAllExtensions readerName
149+ let exts = foldr disableExtension
150+ (foldr enableExtension
145− getDefaultExtensions readerName)
151+ (getDefaultExtensions readerName)
152+ extsToEnable) extsToDisable
153+ mapM_ (\ext ->
154+ unless (extensionEnabled ext allExts) $
155+ throwError $
156+ PandocUnsupportedExtensionError
157+ (drop 4 $ show ext) readerName)
158+ (extsToEnable ++ extsToDisable)
159+ return (r, exts)
146
160
147-- | Read pandoc document from JSON format.
161-- | Read pandoc document from JSON format.
148readJSON :: PandocMonad m
162readJSON :: PandocMonad m
src/Text/Pandoc/Writers.hs+26−9
@@ -70,6 +70,8 @@ module Text.Pandoc.Writers
70 ) where
70 ) where
71
71
72import Prelude
72import Prelude
73+import Control.Monad.Except (throwError)
74+import Control.Monad (unless)
73import Data.Aeson
75import Data.Aeson
74import qualified Data.ByteString.Lazy as BL
76import qualified Data.ByteString.Lazy as BL
75import Data.List (intercalate)
77import Data.List (intercalate)
@@ -78,6 +80,7 @@ import Text.Pandoc.Class
78import Text.Pandoc.Definition
80import Text.Pandoc.Definition
79import Text.Pandoc.Options
81import Text.Pandoc.Options
80import qualified Text.Pandoc.UTF8 as UTF8
82import qualified Text.Pandoc.UTF8 as UTF8
83+import Text.Pandoc.Error
81import Text.Pandoc.Writers.AsciiDoc
84import Text.Pandoc.Writers.AsciiDoc
82import Text.Pandoc.Writers.CommonMark
85import Text.Pandoc.Writers.CommonMark
83import Text.Pandoc.Writers.ConTeXt
86import Text.Pandoc.Writers.ConTeXt
@@ -176,15 +179,29 @@ writers = [
176 ]
179 ]
177
180
178-- | Retrieve writer, extensions based on formatSpec (format+extensions).
181-- | Retrieve writer, extensions based on formatSpec (format+extensions).
179−getWriter :: PandocMonad m => String -> Either String (Writer m, Extensions)
182+getWriter :: PandocMonad m => String -> m (Writer m, Extensions)
180−getWriter s
183+getWriter s =
181− = case parseFormatSpec s of
184+ case parseFormatSpec s of
185+ Left e -> throwError $ PandocAppError
182− Left e -> Left $ intercalate "\n" [m | Message m <- errorMessages e]
186+ $ intercalate "\n" [m | Message m <- errorMessages e]
183− Right (writerName, setExts) ->
187+ Right (writerName, extsToEnable, extsToDisable) ->
184− case lookup writerName writers of
188+ case lookup writerName writers of
185− Nothing -> Left $ "Unknown writer: " ++ writerName
189+ Nothing -> throwError $
186− Just r -> Right (r, setExts $
190+ PandocUnknownWriterError writerName
191+ Just w -> do
192+ let allExts = getAllExtensions writerName
193+ let exts = foldr disableExtension
194+ (foldr enableExtension
187− getDefaultExtensions writerName)
195+ (getDefaultExtensions writerName)
196+ extsToEnable) extsToDisable
197+ mapM_ (\ext ->
198+ unless (extensionEnabled ext allExts) $
199+ throwError $
200+ PandocUnsupportedExtensionError
201+ (drop 4 $ show ext) writerName)
202+ (extsToEnable ++ extsToDisable)
203+ return (w, exts)
204+
188
205
189writeJSON :: PandocMonad m => WriterOptions -> Pandoc -> m Text
206writeJSON :: PandocMonad m => WriterOptions -> Pandoc -> m Text
190writeJSON _ = return . UTF8.toText . BL.toStrict . encode
207writeJSON _ = return . UTF8.toText . BL.toStrict . encode