From 15816853a3611a96994842a34a975e91c253c7ab Mon Sep 17 00:00:00 2001
From: Daniel Bergey <bergey@alum.mit.edu>
Date: Fri, 5 Dec 2014 22:21:19 +0000
Subject: [PATCH] expose warnings from RST reader; refactor

This commit moves some code which was only used for the Markdown Reader
into a generic form which can be used for any Reader.  Otherwise, it
takes naming and interface cues from the preexisting Markdown code.
---
 src/Text/Pandoc.hs                  | 25 ++++++++++++-------------
 src/Text/Pandoc/Parsing.hs          | 10 ++++++++++
 src/Text/Pandoc/Readers/Markdown.hs |  6 +-----
 src/Text/Pandoc/Readers/RST.hs      | 11 +++++++++--
 4 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/src/Text/Pandoc.hs b/src/Text/Pandoc.hs
index 1f22122ac..d2bb85699 100644
--- a/src/Text/Pandoc.hs
+++ b/src/Text/Pandoc.hs
@@ -201,19 +201,18 @@ parseFormatSpec = parse formatSpec ""
                         '-'  -> Set.delete ext
                         _    -> Set.insert ext
 
--- auxiliary function for readers:
-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)
 
+mkStringReaderWithWarnings :: (ReaderOptions -> String -> (Pandoc, [String])) -> Reader
+mkStringReaderWithWarnings r  = StringReader $ \o s -> do
+    let (doc, warnings) = r o s
+    mapM_ warn warnings
+    return doc
+
 mkBSReader :: (ReaderOptions -> BL.ByteString -> (Pandoc, MediaBag)) -> Reader
 mkBSReader r = ByteStringReader (\o s -> return $ r o s)
 
@@ -221,12 +220,12 @@ mkBSReader r = ByteStringReader (\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)
-           ,("rst"          , mkStringReader readRST )
+           ,("markdown"     , mkStringReaderWithWarnings readMarkdownWithWarnings)
+           ,("markdown_strict" , mkStringReaderWithWarnings readMarkdownWithWarnings)
+           ,("markdown_phpextra" , mkStringReaderWithWarnings readMarkdownWithWarnings)
+           ,("markdown_github" , mkStringReaderWithWarnings readMarkdownWithWarnings)
+           ,("markdown_mmd",  mkStringReaderWithWarnings readMarkdownWithWarnings)
+           ,("rst"          , mkStringReaderWithWarnings readRSTWithWarnings )
            ,("mediawiki"    , mkStringReader readMediaWiki)
            ,("docbook"      , mkStringReader readDocBook)
            ,("opml"         , mkStringReader readOPML)
diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs
index 416a7824a..430cfca89 100644
--- a/src/Text/Pandoc/Parsing.hs
+++ b/src/Text/Pandoc/Parsing.hs
@@ -65,6 +65,7 @@ module Text.Pandoc.Parsing ( anyLine,
                              widthsFromIndices,
                              gridTableWith,
                              readWith,
+                             readWithWarnings,
                              readWithM,
                              testStringWith,
                              guardEnabled,
@@ -881,6 +882,15 @@ readWith :: Parser [Char] st a
          -> a
 readWith p t inp = runIdentity $ readWithM p t inp
 
+readWithWarnings :: Parser [Char] ParserState a
+                    -> ParserState
+                    -> String
+                    -> (a, [String])
+readWithWarnings p = readWith $ do
+         doc <- p
+         warnings <- stateWarnings <$> getState
+         return (doc, warnings)
+
 -- | Parse a string with @parser@ (for testing).
 testStringWith :: (Show a, Stream [Char] Identity Char)
                => ParserT [Char] ParserState Identity a
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs
index b70193ad3..2ca3b0eb6 100644
--- a/src/Text/Pandoc/Readers/Markdown.hs
+++ b/src/Text/Pandoc/Readers/Markdown.hs
@@ -79,11 +79,7 @@ readMarkdownWithWarnings :: ReaderOptions -- ^ Reader options
                          -> String        -- ^ String to parse (assuming @'\n'@ line endings)
                          -> (Pandoc, [String])
 readMarkdownWithWarnings opts s =
-  (readWith parseMarkdownWithWarnings) def{ stateOptions = opts } (s ++ "\n\n")
- where parseMarkdownWithWarnings = do
-         doc <- parseMarkdown
-         warnings <- stateWarnings <$> getState
-         return (doc, warnings)
+    (readWithWarnings parseMarkdown) def{ stateOptions = opts } (s ++ "\n\n")
 
 trimInlinesF :: F Inlines -> F Inlines
 trimInlinesF = liftM trimInlines
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 5c67629d6..20729e09a 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -29,7 +29,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 Conversion from reStructuredText to 'Pandoc' document.
 -}
 module Text.Pandoc.Readers.RST (
-                                readRST
+                                readRST,
+                                readRSTWithWarnings
                                ) where
 import Text.Pandoc.Definition
 import Text.Pandoc.Builder (setMeta, fromList)
@@ -55,6 +56,9 @@ readRST :: ReaderOptions -- ^ Reader options
         -> Pandoc
 readRST opts s = (readWith parseRST) def{ stateOptions = opts } (s ++ "\n\n")
 
+readRSTWithWarnings :: ReaderOptions -> String -> (Pandoc, [String])
+readRSTWithWarnings opts s = (readWithWarnings parseRST) def{ stateOptions = opts } (s ++ "\n\n")
+
 type RSTParser = Parser [Char] ParserState
 
 --
@@ -1016,7 +1020,10 @@ renderRole contents fmt role attr = case role of
                 fmtStr = fmt `mplus` newFmt
                 (newRole, newAttr) = inherit attr
                 in renderRole contents fmtStr newRole newAttr
-            Nothing -> return $ B.str contents -- Undefined role
+            Nothing -> do
+                pos <- getPosition
+                addWarning (Just pos) $ "ignoring unknown role :" ++ custom ++ ": in "
+                return $ B.str contents -- Undefined role
  where
    titleRef ref = return $ B.str ref -- FIXME: Not a sensible behaviour
    rfcLink rfcNo = B.link rfcUrl ("RFC " ++ rfcNo) $ B.str ("RFC " ++ rfcNo)