From 5c3423f2e2b441f9fe630538906b5fc1436e04f3 Mon Sep 17 00:00:00 2001
From: John MacFarlane <jgm@berkeley.edu>
Date: Thu, 28 Jul 2022 11:15:25 -0700
Subject: [PATCH] DokuWiki reader: support latex plugin and math.

The `tex_math_dollars` extension is now supported for `dokuwiki`
(but off by default).

Content inside `<latex>...</latex>` is parsed as raw LaTeX inline,
and inside `<LATEX>..</LATEX>` as raw LaTeX block.

In addition, this commit changes the behavior of `<php>...</php>` so
that instead of producing a code block, it produces raw HTML
with `<?php ... ?>`.

Closes #8178.
---
 src/Text/Pandoc/Extensions.hs       |  4 ++-
 src/Text/Pandoc/Readers/DokuWiki.hs | 50 ++++++++++++++++++-----------
 test/Tests/Readers/DokuWiki.hs      |  4 +--
 test/command/8178.md                | 25 +++++++++++++++
 4 files changed, 61 insertions(+), 22 deletions(-)
 create mode 100644 test/command/8178.md

diff --git a/src/Text/Pandoc/Extensions.hs b/src/Text/Pandoc/Extensions.hs
index 1579dfaeb..cc4f0c730 100644
--- a/src/Text/Pandoc/Extensions.hs
+++ b/src/Text/Pandoc/Extensions.hs
@@ -592,7 +592,9 @@ getAllExtensions f = universalExtensions <> getAll f
     extensionsFromList
     [ Ext_smart ]
   getAll "vimwiki"         = autoIdExtensions
-  getAll "dokuwiki"        = autoIdExtensions
+  getAll "dokuwiki"        = autoIdExtensions <>
+    extensionsFromList
+    [ Ext_tex_math_dollars ]
   getAll "tikiwiki"        = autoIdExtensions
   getAll "rst"             = autoIdExtensions <>
     extensionsFromList
diff --git a/src/Text/Pandoc/Readers/DokuWiki.hs b/src/Text/Pandoc/Readers/DokuWiki.hs
index 82df2784e..d1b673611 100644
--- a/src/Text/Pandoc/Readers/DokuWiki.hs
+++ b/src/Text/Pandoc/Readers/DokuWiki.hs
@@ -117,8 +117,8 @@ inline'' = br
       <|> footnote
       <|> inlineCode
       <|> inlineFile
-      <|> inlineHtml
-      <|> inlinePhp
+      <|> inlineRaw
+      <|> math
       <|> autoLink
       <|> autoEmail
       <|> notoc
@@ -209,11 +209,22 @@ inlineCode = codeTag B.codeWith "code"
 inlineFile :: PandocMonad m => DWParser m B.Inlines
 inlineFile = codeTag B.codeWith "file"
 
-inlineHtml :: PandocMonad m => DWParser m B.Inlines
-inlineHtml = try $ B.rawInline "html" <$ string "<html>" <*> manyTillChar anyChar (try $ string "</html>")
+inlineRaw :: PandocMonad m => DWParser m B.Inlines
+inlineRaw = try $ do
+  char '<'
+  fmt <- oneOfStrings ["html", "php", "latex"]
+  -- LaTeX via https://www.dokuwiki.org/plugin:latex
+  char '>'
+  contents <- manyTillChar anyChar
+                (try $ string "</" *> string (T.unpack fmt) *> char '>')
+  return $
+    case T.toLower fmt of
+         "php" -> B.rawInline "html" $ "<?php " <> contents <> " ?>"
+         f -> B.rawInline f contents
 
-inlinePhp :: PandocMonad m => DWParser m B.Inlines
-inlinePhp = try $ B.codeWith ("", ["php"], []) <$ string "<php>" <*> manyTillChar anyChar (try $ string "</php>")
+-- see https://www.dokuwiki.org/plugin:latex
+math :: PandocMonad m => DWParser m B.Inlines
+math = (B.displayMath <$> mathDisplay) <|> (B.math <$> mathInline)
 
 makeLink :: (Text, Text) -> B.Inlines
 makeLink (text, url) = B.link url "" $ B.str text
@@ -410,8 +421,7 @@ blockElements = horizontalLine
             <|> quote
             <|> blockCode
             <|> blockFile
-            <|> blockHtml
-            <|> blockPhp
+            <|> blockRaw
             <|> table
 
 horizontalLine :: PandocMonad m => DWParser m B.Blocks
@@ -462,17 +472,19 @@ quote = try $ nestedQuote 0
     quoteContinuation level = mconcat <$> many (try $ prefix level *> contents level)
     nestedQuote level = B.blockQuote <$ char '>' <*> quoteContents (level + 1 :: Int)
 
-blockHtml :: PandocMonad m => DWParser m B.Blocks
-blockHtml = try $ B.rawBlock "html"
-  <$  string "<HTML>"
-  <*  optional (manyTill spaceChar eol)
-  <*> manyTillChar anyChar (try $ string "</HTML>")
-
-blockPhp :: PandocMonad m => DWParser m B.Blocks
-blockPhp = try $ B.codeBlockWith ("", ["php"], [])
-  <$  string "<PHP>"
-  <*  optional (manyTill spaceChar eol)
-  <*> manyTillChar anyChar (try $ string "</PHP>")
+blockRaw :: PandocMonad m => DWParser m B.Blocks
+blockRaw = try $ do
+  char '<'
+  fmt <- oneOfStrings ["HTML", "PHP", "LATEX"]
+  -- LaTeX via https://www.dokuwiki.org/plugin:latex
+  char '>'
+  optional (manyTill spaceChar eol)
+  contents <- manyTillChar anyChar
+               (try $ string "</" *> string (T.unpack fmt) *> char '>')
+  return $
+    case T.toLower fmt of
+         "php" -> B.rawBlock "html" $ "<?php " <> contents <> " ?>"
+         f -> B.rawBlock f contents
 
 table :: PandocMonad m => DWParser m B.Blocks
 table = do
diff --git a/test/Tests/Readers/DokuWiki.hs b/test/Tests/Readers/DokuWiki.hs
index d08e72c01..56275d3d2 100644
--- a/test/Tests/Readers/DokuWiki.hs
+++ b/test/Tests/Readers/DokuWiki.hs
@@ -80,7 +80,7 @@ tests = [ testGroup "inlines"
             para (rawInline "html" "\nThis is some <span style=\"color:red;font-size:150%;\">inline HTML</span>\n")
           , "Inline PHP" =:
             "<php>echo '<p>Hello World</p>';</php>" =?>
-            para (codeWith ("", ["php"], []) "echo '<p>Hello World</p>';")
+            para (rawInline "html" "<?php echo '<p>Hello World</p>'; ?>")
           , "Linebreak" =:
             T.unlines [ "This is some text with some linebreaks\\\\ Note that the"
                       , "two backslashes are only recognized at the end of a line\\\\"
@@ -260,7 +260,7 @@ tests = [ testGroup "inlines"
                     , "echo '<p>Hello World</p>';"
                     , "</PHP>"
                     ] =?>
-          codeBlockWith ("", ["php"], []) "echo '<p>Hello World</p>';\n"
+          rawBlock "html" "<?php echo '<p>Hello World</p>';\n ?>"
         , "Quote" =:
           T.unlines [ "> foo"
                     , ">no space is required after >"
diff --git a/test/command/8178.md b/test/command/8178.md
new file mode 100644
index 000000000..da6d2d822
--- /dev/null
+++ b/test/command/8178.md
@@ -0,0 +1,25 @@
+```
+% pandoc -f dokuwiki -t native
+<latex>$\sum_{\substack{(i,j) \in I^2 \i \neq j}}$</latex>
+^D
+[ Para
+    [ RawInline
+        (Format "latex")
+        "$\\sum_{\\substack{(i,j) \\in I^2 \\i \\neq j}}$"
+    ]
+]
+```
+
+```
+% pandoc -f dokuwiki+tex_math_dollars -t native
+$mc^2$
+^D
+[ Para [ Math InlineMath "mc^2" ] ]
+```
+
+```
+% pandoc -f dokuwiki -t native
+$mc^2$
+^D
+[ Para [ Str "$mc^2$" ] ]
+```