From 68b6b9f652125318e82819918a79f8075924d93e Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Thu, 2 Jul 2015 19:16:30 +0200
Subject: [PATCH 1/4] Readers.RST: Parse field list name
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

“Inline markup is parsed in field names.” [1]

[1] http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#field-lists
---
 src/Text/Pandoc/Readers/RST.hs |  2 +-
 tests/Tests/Readers/RST.hs     | 22 ++++++++++++++++++++--
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 38de77f9f..95fa5c497 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -209,7 +209,7 @@ rawFieldListItem minIndent = try $ do
 fieldListItem :: Int -> RSTParser (Inlines, [Blocks])
 fieldListItem minIndent = try $ do
   (name, raw) <- rawFieldListItem minIndent
-  let term = B.str name
+  term <- parseFromString (trimInlines . mconcat <$> many inline) name
   contents <- parseFromString parseBlocks raw
   optional blanklines
   return (term, [contents])
diff --git a/tests/Tests/Readers/RST.hs b/tests/Tests/Readers/RST.hs
index 7f1f3d044..5e4753229 100644
--- a/tests/Tests/Readers/RST.hs
+++ b/tests/Tests/Readers/RST.hs
@@ -39,11 +39,11 @@ tests = [ "line block with blank line" =:
            =?> ( doc
                $ para "para" <>
                  definitionList [ (str "Hostname", [para "media08"])
-                                , (str "IP address", [para "10.0.0.19"])
+                                , (text "IP address", [para "10.0.0.19"])
                                 , (str "Size", [para "3ru"])
                                 , (str "Version", [para "1"])
                                 , (str "Indentation", [para "Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other."])
-                                , (str "Parameter i", [para "integer"])
+                                , (text "Parameter i", [para "integer"])
                                 , (str "Final", [para "item on two lines"])
                               ])
         , "initial field list" =: unlines
@@ -60,6 +60,24 @@ tests = [ "line block with blank line" =:
                $ setMeta "title" ("Title" :: Inlines)
                $ setMeta "subtitle" ("Subtitle" :: Inlines)
                $ doc mempty )
+        , "field list name with inline markup" =: unlines
+             [ "the following field list is not metadata"
+             , ""
+             , ":*one*: emphasis"
+             , ":two_: reference"
+             , ":`three`_: another one"
+             , ":``four``: literal"
+             , ""
+             , ".. _two: http://example.com"
+             , ".. _three: http://example.org"
+             ]
+           =?> (doc
+               $ para "the following field list is not metadata" <>
+                 definitionList [ (emph "one", [para "emphasis"])
+                                , (link "http://example.com" "" "two", [para "reference"])
+                                , (link "http://example.org" "" "three", [para "another one"])
+                                , (code "four", [para "literal"])
+                                ])
         , "URLs with following punctuation" =:
           ("http://google.com, http://yahoo.com; http://foo.bar.baz.\n" ++
            "http://foo.bar/baz_(bam) (http://foo.bar)") =?>

From b2adf44e753d7ab75bdc57e2fdedfaa621211b2f Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Fri, 3 Jul 2015 16:29:46 +0200
Subject: [PATCH 2/4] Readers.RST: Factor out inline markup string parsing

---
 src/Text/Pandoc/Readers/RST.hs | 26 +++++++++++---------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs
index 95fa5c497..678eecc52 100644
--- a/src/Text/Pandoc/Readers/RST.hs
+++ b/src/Text/Pandoc/Readers/RST.hs
@@ -209,7 +209,7 @@ rawFieldListItem minIndent = try $ do
 fieldListItem :: Int -> RSTParser (Inlines, [Blocks])
 fieldListItem minIndent = try $ do
   (name, raw) <- rawFieldListItem minIndent
-  term <- parseFromString (trimInlines . mconcat <$> many inline) name
+  term <- parseInlineFromString name
   contents <- parseFromString parseBlocks raw
   optional blanklines
   return (term, [contents])
@@ -229,8 +229,7 @@ fieldList = try $ do
 lineBlock :: RSTParser Blocks
 lineBlock = try $ do
   lines' <- lineBlockLines
-  lines'' <- mapM (parseFromString
-                   (trimInlines . mconcat <$> many inline)) lines'
+  lines'' <- mapM parseInlineFromString lines'
   return $ B.para (mconcat $ intersperse B.linebreak lines'')
 
 --
@@ -549,39 +548,33 @@ directive' = do
         "role" -> addNewRole top $ map (\(k,v) -> (k, trim v)) fields
         "container" -> parseFromString parseBlocks body'
         "replace" -> B.para <$>  -- consumed by substKey
-                   parseFromString (trimInlines . mconcat <$> many inline)
-                   (trim top)
+                   parseInlineFromString (trim top)
         "unicode" -> B.para <$>  -- consumed by substKey
-                   parseFromString (trimInlines . mconcat <$> many inline)
-                   (trim $ unicodeTransform top)
+                   parseInlineFromString (trim $ unicodeTransform top)
         "compound" -> parseFromString parseBlocks body'
         "pull-quote" -> B.blockQuote <$> parseFromString parseBlocks body'
         "epigraph" -> B.blockQuote <$> parseFromString parseBlocks body'
         "highlights" -> B.blockQuote <$> parseFromString parseBlocks body'
-        "rubric" -> B.para . B.strong <$> parseFromString
-                          (trimInlines . mconcat <$> many inline) top
+        "rubric" -> B.para . B.strong <$> parseInlineFromString top
         _ | label `elem` ["attention","caution","danger","error","hint",
                           "important","note","tip","warning"] ->
            do let tit = B.para $ B.strong $ B.str label
               bod <- parseFromString parseBlocks $ top ++ "\n\n" ++ body'
               return $ B.blockQuote $ tit <> bod
         "admonition" ->
-           do tit <- B.para . B.strong <$> parseFromString
-                          (trimInlines . mconcat <$> many inline) top
+           do tit <- B.para . B.strong <$> parseInlineFromString top
               bod <- parseFromString parseBlocks body'
               return $ B.blockQuote $ tit <> bod
         "sidebar" ->
            do let subtit = maybe "" trim $ lookup "subtitle" fields
-              tit <- B.para . B.strong <$> parseFromString
-                          (trimInlines . mconcat <$> many inline)
+              tit <- B.para . B.strong <$> parseInlineFromString
                           (trim top ++ if null subtit
                                           then ""
                                           else (":  " ++ subtit))
               bod <- parseFromString parseBlocks body'
               return $ B.blockQuote $ tit <> bod
         "topic" ->
-           do tit <- B.para . B.strong <$> parseFromString
-                          (trimInlines . mconcat <$> many inline) top
+           do tit <- B.para . B.strong <$> parseInlineFromString top
               bod <- parseFromString parseBlocks body'
               return $ tit <> bod
         "default-role" -> mempty <$ updateState (\s ->
@@ -962,6 +955,9 @@ inline = choice [ whitespace
                 , escapedChar
                 , symbol ] <?> "inline"
 
+parseInlineFromString :: String -> RSTParser Inlines
+parseInlineFromString = parseFromString (trimInlines . mconcat <$> many inline)
+
 hyphens :: RSTParser Inlines
 hyphens = do
   result <- many1 (char '-')

From 8577007d9b9643e1f4620d3d1ac1642973c89082 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Fri, 3 Jul 2015 16:40:59 +0200
Subject: [PATCH 3/4] Tests.Readers.RST: Group field list tests

---
 tests/Tests/Readers/RST.hs | 50 ++++++++++++++++++++------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/tests/Tests/Readers/RST.hs b/tests/Tests/Readers/RST.hs
index 5e4753229..b8b170054 100644
--- a/tests/Tests/Readers/RST.hs
+++ b/tests/Tests/Readers/RST.hs
@@ -22,7 +22,8 @@ tests :: [Test]
 tests = [ "line block with blank line" =:
           "| a\n|\n|  b" =?> para (str "a") <>
                              para (str "\160b")
-        , "field list" =: unlines
+        , testGroup "field list"
+          [ "general" =: unlines
              [ "para"
              , ""
              , ":Hostname: media08"
@@ -36,17 +37,17 @@ tests = [ "line block with blank line" =:
              , ":Parameter i: integer"
              , ":Final: item"
              , "  on two lines" ]
-           =?> ( doc
-               $ para "para" <>
-                 definitionList [ (str "Hostname", [para "media08"])
-                                , (text "IP address", [para "10.0.0.19"])
-                                , (str "Size", [para "3ru"])
-                                , (str "Version", [para "1"])
-                                , (str "Indentation", [para "Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other."])
-                                , (text "Parameter i", [para "integer"])
-                                , (str "Final", [para "item on two lines"])
-                              ])
-        , "initial field list" =: unlines
+             =?> ( doc
+                 $ para "para" <>
+                   definitionList [ (str "Hostname", [para "media08"])
+                                  , (text "IP address", [para "10.0.0.19"])
+                                  , (str "Size", [para "3ru"])
+                                  , (str "Version", [para "1"])
+                                  , (str "Indentation", [para "Since the field marker may be quite long, the second and subsequent lines of the field body do not have to line up with the first line, but they must be indented relative to the field name marker, and they must line up with each other."])
+                                  , (text "Parameter i", [para "integer"])
+                                  , (str "Final", [para "item on two lines"])
+                                  ])
+          , "metadata" =: unlines
              [ "====="
              , "Title"
              , "====="
@@ -56,11 +57,11 @@ tests = [ "line block with blank line" =:
              , ""
              , ":Version: 1"
              ]
-           =?> ( setMeta "version" (para "1")
-               $ setMeta "title" ("Title" :: Inlines)
-               $ setMeta "subtitle" ("Subtitle" :: Inlines)
-               $ doc mempty )
-        , "field list name with inline markup" =: unlines
+             =?> ( setMeta "version" (para "1")
+                 $ setMeta "title" ("Title" :: Inlines)
+                 $ setMeta "subtitle" ("Subtitle" :: Inlines)
+                 $ doc mempty )
+          , "with inline markup" =: unlines
              [ "the following field list is not metadata"
              , ""
              , ":*one*: emphasis"
@@ -71,13 +72,14 @@ tests = [ "line block with blank line" =:
              , ".. _two: http://example.com"
              , ".. _three: http://example.org"
              ]
-           =?> (doc
-               $ para "the following field list is not metadata" <>
-                 definitionList [ (emph "one", [para "emphasis"])
-                                , (link "http://example.com" "" "two", [para "reference"])
-                                , (link "http://example.org" "" "three", [para "another one"])
-                                , (code "four", [para "literal"])
-                                ])
+             =?> ( doc
+                 $ para "the following field list is not metadata" <>
+                   definitionList [ (emph "one", [para "emphasis"])
+                                  , (link "http://example.com" "" "two", [para "reference"])
+                                  , (link "http://example.org" "" "three", [para "another one"])
+                                  , (code "four", [para "literal"])
+                                  ])
+          ]
         , "URLs with following punctuation" =:
           ("http://google.com, http://yahoo.com; http://foo.bar.baz.\n" ++
            "http://foo.bar/baz_(bam) (http://foo.bar)") =?>

From d9e17cb3f76f324bad8bbbb931456f5b152adca9 Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Fri, 3 Jul 2015 16:56:25 +0200
Subject: [PATCH 4/4] Tests.Readers.RST: Test metadata with inline markup too

---
 tests/Tests/Readers/RST.hs | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/tests/Tests/Readers/RST.hs b/tests/Tests/Readers/RST.hs
index b8b170054..c05f2f5e4 100644
--- a/tests/Tests/Readers/RST.hs
+++ b/tests/Tests/Readers/RST.hs
@@ -62,7 +62,9 @@ tests = [ "line block with blank line" =:
                  $ setMeta "subtitle" ("Subtitle" :: Inlines)
                  $ doc mempty )
           , "with inline markup" =: unlines
-             [ "the following field list is not metadata"
+             [ ":*Date*: today"
+             , ""
+             , ".."
              , ""
              , ":*one*: emphasis"
              , ":two_: reference"
@@ -72,9 +74,9 @@ tests = [ "line block with blank line" =:
              , ".. _two: http://example.com"
              , ".. _three: http://example.org"
              ]
-             =?> ( doc
-                 $ para "the following field list is not metadata" <>
-                   definitionList [ (emph "one", [para "emphasis"])
+             =?> ( setMeta "date" (str "today")
+                 $ doc
+                 $ definitionList [ (emph "one", [para "emphasis"])
                                   , (link "http://example.com" "" "two", [para "reference"])
                                   , (link "http://example.org" "" "three", [para "another one"])
                                   , (code "four", [para "literal"])