From 618dc294f93f1865dcdfbfda21003745b4d6b389 Mon Sep 17 00:00:00 2001
From: Greg Maslov <gmaslov@bootis.org>
Date: Sat, 24 Mar 2012 21:30:10 -0400
Subject: [PATCH 1/2] Add parsing support for the rST default-role directive.

---
 src/Text/Pandoc/Parsing.hs     |  6 ++++--
 src/Text/Pandoc/Readers/RST.hs | 34 +++++++++++++++++++++++++++++++---
 tests/rst-reader.native        |  7 ++++++-
 tests/rst-reader.rst           | 18 ++++++++++++++++++
 4 files changed, 59 insertions(+), 6 deletions(-)

diff --git a/src/Text/Pandoc/Parsing.hs b/src/Text/Pandoc/Parsing.hs
index 725621ce2..22a8d4d50 100644
--- a/src/Text/Pandoc/Parsing.hs
+++ b/src/Text/Pandoc/Parsing.hs
@@ -652,7 +652,8 @@ data ParserState = ParserState
       stateExamples        :: M.Map String Int, -- ^ Map from example labels to numbers 
       stateHasChapters     :: Bool,          -- ^ True if \chapter encountered
       stateApplyMacros     :: Bool,          -- ^ Apply LaTeX macros?
-      stateMacros          :: [Macro]        -- ^ List of macros defined so far
+      stateMacros          :: [Macro],       -- ^ List of macros defined so far
+      stateRstDefaultRole  :: String         -- ^ Current rST default interpreted text role
     }
     deriving Show
 
@@ -682,7 +683,8 @@ defaultParserState =
                   stateExamples        = M.empty,
                   stateHasChapters     = False,
                   stateApplyMacros     = True,
-                  stateMacros          = []}
+                  stateMacros          = [],
+                  stateRstDefaultRole  = "title-reference"}
 
 data HeaderType 
     = SingleHeader Char  -- ^ Single line of characters underneath
diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 30d9aae44..2fbf11cf7 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -129,6 +129,7 @@ block = choice [ codeBlock
                , imageBlock
                , customCodeBlock
                , mathBlock
+               , defaultRoleBlock
                , unknownDirective
                , header
                , hrule
@@ -532,6 +533,21 @@ bulletList :: GenParser Char ParserState Block
 bulletList = many1 (listItem bulletListStart) >>= 
              return . BulletList . compactify
 
+--
+-- default-role block
+--
+
+defaultRoleBlock :: GenParser Char ParserState Block
+defaultRoleBlock = try $ do
+    string ".. default-role:: "
+    role <- manyTill anyChar newline >>= return . removeLeadingTrailingSpace
+    updateState $ \s -> s { stateRstDefaultRole =
+        if null role
+           then stateRstDefaultRole defaultParserState
+           else role
+        }
+    return Null
+
 --
 -- unknown directive (e.g. comment)
 --
@@ -805,13 +821,25 @@ strong :: GenParser Char ParserState Inline
 strong = enclosed (string "**") (try $ string "**") inline >>= 
          return . Strong . normalizeSpaces
 
-interpreted :: [Char] -> GenParser Char st [Char]
+-- Parses inline interpreted text which is required to have the given role.
+-- This decision is based on the role marker (if present),
+-- and the current default interpreted text role.
+interpreted :: [Char] -> GenParser Char ParserState [Char]
 interpreted role = try $ do
+  state <- getState
+  if role == stateRstDefaultRole state
+     then try markedInterpretedText <|> unmarkedInterpretedText
+     else     markedInterpretedText
+ where
+  markedInterpretedText = try (roleMarker >> unmarkedInterpretedText)
+                          <|> (unmarkedInterpretedText >>= (\txt -> roleMarker >> return txt))
+  roleMarker = string $ ":" ++ role ++ ":"
   -- Note, this doesn't precisely implement the complex rule in
   -- http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#inline-markup-recognition-rules
   -- but it should be good enough for most purposes
-  result <- enclosed (string $ ":" ++ role ++ ":`") (char '`') anyChar
-  return result
+  unmarkedInterpretedText = do
+      result <- enclosed (char '`') (char '`') anyChar
+      return result
 
 superscript :: GenParser Char ParserState Inline
 superscript = interpreted "sup" >>= \x -> return (Superscript [Str x])
diff --git a/tests/rst-reader.native b/tests/rst-reader.native
index e0eb4d438..5bb646f61 100644
--- a/tests/rst-reader.native
+++ b/tests/rst-reader.native
@@ -312,4 +312,9 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
 ,Para [Math DisplayMath "E = mc^2"]
 ,Para [Math DisplayMath "E = mc^2",Math DisplayMath "\\alpha = \\beta"]
 ,Para [Math DisplayMath "E &= mc^2\\\\\nF &= \\pi E",Math DisplayMath "F &= \\gamma \\alpha^2"]
-,Para [Str "All",Space,Str "done",Str "."]]
+,Para [Str "All",Space,Str "done",Str "."]
+,Header 1 [Str "Default",Str "-",Str "Role"]
+,Para [Str "Try",Space,Str "changing",Space,Str "the",Space,Str "default",Space,Str "role",Space,Str "to",Space,Str "a",Space,Str "few",Space,Str "different",Space,Str "things",Str "."]
+,Para [Str "Inline",Space,Str "math",Str ":",Space,Math InlineMath "E=mc^2",Space,Str "or",Space,Math InlineMath "E=mc^2",Space,Str "or",Space,Math InlineMath "E=mc^2",Str ".",Space,Str "Other",Space,Str "roles",Str ":",Space,Superscript [Str "super"],Str ",",Space,Subscript [Str "sub"],Str "."]
+,Para [Str "Some",Space,Superscript [Str "of"],Space,Str "these",Space,Superscript [Str "words"],Space,Str "are",Space,Str "in",Space,Superscript [Str "superscript"],Str "."]
+,Para [Str "Reset",Space,Str "default",Str "-",Str "role",Space,Str "to",Space,Str "the",Space,Str "default",Space,Str "default",Str "."]]
diff --git a/tests/rst-reader.rst b/tests/rst-reader.rst
index cfebd2054..d06d70907 100644
--- a/tests/rst-reader.rst
+++ b/tests/rst-reader.rst
@@ -565,3 +565,21 @@ display math:
 
 All done.
 
+Default-Role
+============
+
+Try changing the default role to a few different things.
+
+.. default-role:: math
+
+Inline math: `E=mc^2` or :math:`E=mc^2` or `E=mc^2`:math:.
+Other roles: :sup:`super`, `sub`:sub:.
+
+.. default-role:: sup
+
+Some `of` these :sup:`words` are in `superscript`:sup:.
+
+Reset default-role to the default default.
+
+.. default-role::
+

From 4a1ba8ce49ffc3c2a154721dc18fc48896f97f59 Mon Sep 17 00:00:00 2001
From: Greg Maslov <gmaslov@bootis.org>
Date: Sun, 25 Mar 2012 05:03:35 -0400
Subject: [PATCH 2/2] Oops! Forgot to munch whitespace / ignore body after
 directive.

---
 src/Text/Pandoc/Readers/RST.hs |  5 ++++-
 tests/rst-reader.native        |  5 ++++-
 tests/rst-reader.rst           | 10 ++++++++++
 3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 2fbf11cf7..35fe5d768 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -539,13 +539,16 @@ bulletList = many1 (listItem bulletListStart) >>=
 
 defaultRoleBlock :: GenParser Char ParserState Block
 defaultRoleBlock = try $ do
-    string ".. default-role:: "
+    string ".. default-role::"
+    -- doesn't enforce any restrictions on the role name; embedded spaces shouldn't be allowed, for one
     role <- manyTill anyChar newline >>= return . removeLeadingTrailingSpace
     updateState $ \s -> s { stateRstDefaultRole =
         if null role
            then stateRstDefaultRole defaultParserState
            else role
         }
+    -- skip body of the directive if it exists
+    many $ blanklines <|> (spaceChar >> manyTill anyChar newline)
     return Null
 
 --
diff --git a/tests/rst-reader.native b/tests/rst-reader.native
index 5bb646f61..bf794c849 100644
--- a/tests/rst-reader.native
+++ b/tests/rst-reader.native
@@ -315,6 +315,9 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite",Str ":
 ,Para [Str "All",Space,Str "done",Str "."]
 ,Header 1 [Str "Default",Str "-",Str "Role"]
 ,Para [Str "Try",Space,Str "changing",Space,Str "the",Space,Str "default",Space,Str "role",Space,Str "to",Space,Str "a",Space,Str "few",Space,Str "different",Space,Str "things",Str "."]
+,Header 2 [Str "Doesn",Str "\8217",Str "t",Space,Str "Break",Space,Str "Title",Space,Str "Parsing"]
 ,Para [Str "Inline",Space,Str "math",Str ":",Space,Math InlineMath "E=mc^2",Space,Str "or",Space,Math InlineMath "E=mc^2",Space,Str "or",Space,Math InlineMath "E=mc^2",Str ".",Space,Str "Other",Space,Str "roles",Str ":",Space,Superscript [Str "super"],Str ",",Space,Subscript [Str "sub"],Str "."]
+,Para [Math DisplayMath "\\alpha = beta",Math DisplayMath "E = mc^2"]
 ,Para [Str "Some",Space,Superscript [Str "of"],Space,Str "these",Space,Superscript [Str "words"],Space,Str "are",Space,Str "in",Space,Superscript [Str "superscript"],Str "."]
-,Para [Str "Reset",Space,Str "default",Str "-",Str "role",Space,Str "to",Space,Str "the",Space,Str "default",Space,Str "default",Str "."]]
+,Para [Str "Reset",Space,Str "default",Str "-",Str "role",Space,Str "to",Space,Str "the",Space,Str "default",Space,Str "default",Str "."]
+,Para [Str "And",Space,Str "now",Space,Str "`",Str "some",Str "-",Str "invalid",Str "-",Str "string",Str "-",Str "3231231",Str "`",Space,Str "is",Space,Str "nonsense",Str "."]]
diff --git a/tests/rst-reader.rst b/tests/rst-reader.rst
index d06d70907..abe6d4f69 100644
--- a/tests/rst-reader.rst
+++ b/tests/rst-reader.rst
@@ -572,9 +572,17 @@ Try changing the default role to a few different things.
 
 .. default-role:: math
 
+Doesn't Break Title Parsing
+---------------------------
+
 Inline math: `E=mc^2` or :math:`E=mc^2` or `E=mc^2`:math:.
 Other roles: :sup:`super`, `sub`:sub:.
 
+.. math::
+    \alpha = beta
+
+    E = mc^2
+
 .. default-role:: sup
 
 Some `of` these :sup:`words` are in `superscript`:sup:.
@@ -583,3 +591,5 @@ Reset default-role to the default default.
 
 .. default-role::
 
+And now `some-invalid-string-3231231` is nonsense.
+