From 6018a2324d4eddc3844aa4c00b17294e85003750 Mon Sep 17 00:00:00 2001
From: Alexander Krotov <ilabdsf@gmail.com>
Date: Tue, 14 Nov 2017 22:34:47 +0300
Subject: [PATCH] Muse reader: Add Text::Amuse footnote extensions

Footnote end is indicated by indentation,
so footnotes can be placed anywhere in the text,
not just at the end of it.
---
 src/Text/Pandoc/Readers/Muse.hs | 35 +++++++++++++++++++++++++------
 test/Tests/Readers/Muse.hs      | 37 +++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 6 deletions(-)

diff --git a/src/Text/Pandoc/Readers/Muse.hs b/src/Text/Pandoc/Readers/Muse.hs
index 13b517d09..8c785e002 100644
--- a/src/Text/Pandoc/Readers/Muse.hs
+++ b/src/Text/Pandoc/Readers/Muse.hs
@@ -189,7 +189,8 @@ blockElements = choice [ comment
                        , definitionList
                        , table
                        , commentTag
-                       , noteBlock
+                       , amuseNoteBlock
+                       , emacsNoteBlock
                        ]
 
 comment :: PandocMonad m => MuseParser m (F Blocks)
@@ -308,8 +309,26 @@ noteMarker = try $ do
   char '['
   many1Till digit $ char ']'
 
-noteBlock :: PandocMonad m => MuseParser m (F Blocks)
-noteBlock = try $ do
+-- Amusewiki version of note
+-- Parsing is similar to list item, except that note marker is used instead of list marker
+amuseNoteBlock :: PandocMonad m => MuseParser m (F Blocks)
+amuseNoteBlock = try $ do
+  guardEnabled Ext_amuse
+  pos <- getPosition
+  ref <- noteMarker <* skipSpaces
+  content <- listItemContents $ 2 + length ref
+  oldnotes <- stateNotes' <$> getState
+  case M.lookup ref oldnotes of
+    Just _  -> logMessage $ DuplicateNoteReference ref pos
+    Nothing -> return ()
+  updateState $ \s -> s{ stateNotes' = M.insert ref (pos, content) oldnotes }
+  return mempty
+
+-- Emacs version of note
+-- Notes are allowed only at the end of text, no indentation is required.
+emacsNoteBlock :: PandocMonad m => MuseParser m (F Blocks)
+emacsNoteBlock = try $ do
+  guardDisabled Ext_amuse
   pos <- getPosition
   ref <- noteMarker <* skipSpaces
   content <- mconcat <$> blocksTillNote
@@ -376,9 +395,8 @@ listStart marker = try $ do
   postWhitespace <- length <$> many1 spaceChar
   return $ preWhitespace + markerLength + postWhitespace
 
-listItem :: PandocMonad m => MuseParser m Int -> MuseParser m (F Blocks)
-listItem start = try $ do
-  markerLength <- start
+listItemContents :: PandocMonad m => Int -> MuseParser m (F Blocks)
+listItemContents markerLength = do
   firstLine <- anyLineNewline
   restLines <- many $ listLine markerLength
   blank <- option "" ("\n" <$ blankline)
@@ -386,6 +404,11 @@ listItem start = try $ do
   rest <- many $ listContinuation markerLength
   parseFromString (withListContext parseBlocks) $ concat (first:rest) ++ "\n"
 
+listItem :: PandocMonad m => MuseParser m Int -> MuseParser m (F Blocks)
+listItem start = try $ do
+  markerLength <- start
+  listItemContents markerLength
+
 bulletListItems :: PandocMonad m => MuseParser m (F [Blocks])
 bulletListItems = sequence <$> many1 (listItem bulletListStart)
 
diff --git a/test/Tests/Readers/Muse.hs b/test/Tests/Readers/Muse.hs
index b4e5dd05e..a9aa4cf12 100644
--- a/test/Tests/Readers/Muse.hs
+++ b/test/Tests/Readers/Muse.hs
@@ -377,6 +377,43 @@ tests =
                     ] =?>
           para (text "Start recursion here" <>
                 note (para "Recursion continues here[1]"))
+        , testGroup "Multiparagraph footnotes"
+          [ "Amusewiki multiparagraph footnotes" =:
+            T.unlines [ "Multiparagraph[1] footnotes[2]"
+                      , ""
+                      , "[1] First footnote paragraph"
+                      , ""
+                      , "    Second footnote paragraph"
+                      , "Not a note"
+                      , "[2] Second footnote"
+                      ] =?>
+            para (text "Multiparagraph" <>
+                  note (para "First footnote paragraph" <>
+                        para "Second footnote paragraph") <>
+                  text " footnotes" <>
+                  note (para "Second footnote")) <>
+            para (text "Not a note")
+          , test emacsMuse "Emacs multiparagraph footnotes"
+            (T.unlines
+              [ "First footnote reference[1] and second footnote reference[2]."
+              , ""
+              , "[1] First footnote paragraph"
+              , ""
+              , "Second footnote"
+              , "paragraph"
+              , ""
+              , "[2] Third footnote paragraph"
+              , ""
+              , "Fourth footnote paragraph"
+              ] =?>
+            para (text "First footnote reference" <>
+                  note (para "First footnote paragraph" <>
+                        para "Second footnote paragraph") <>
+                  text " and second footnote reference" <>
+                  note (para "Third footnote paragraph" <>
+                        para "Fourth footnote paragraph") <>
+                  text "."))
+          ]
         ]
       ]
     , testGroup "Tables"