git.iko.soy/typeable/pandoc
on master help sign in
Org reader: Support more inline/display math variants

Support all of the following variants as valid ways to define inline or display math inlines: - `\[..\]` (display) - `$$..$$` (display) - `\(..\)` (inline) - `$..$` (inline) This closes #1223. Again.

commit1715d7cee0b9388ac77b8b2a31fcbb00ead80adf authorAlbert Krewinkel <tarleb@moltkeplatz.de> dateThu 10 Apr 2014, 15:11 (13 years ago) parenta9eb0ca
2 files changed+56−8
src/Text/Pandoc/Readers/Org.hs+26−2 tests/Tests/Readers/Org.hs+30−6
src/Text/Pandoc/Readers/Org.hs+26−2
@@ -512,6 +512,7 @@ inline =
512512 , underline
513513 , code
514514 , math
515+ , displayMath
515516 , verbatim
516517 , subscript
517518 , superscript
@@ -607,7 +608,15 @@ verbatim :: OrgParser Inlines
607608verbatim = B.rawInline "" <$> verbatimBetween '~'
608609
609610math :: OrgParser Inlines
610−math = B.math <$> mathStringBetween '$'
611+math = B.math <$> choice [ math1CharBetween '$'
612+ , mathStringBetween '$'
613+ , rawMathBetween "\\(" "\\)"
614+ ]
615+
616+displayMath :: OrgParser Inlines
617+displayMath = B.displayMath <$> choice [ rawMathBetween "\\[" "\\]"
618+ , rawMathBetween "$$" "$$"
619+ ]
611620
612621subscript :: OrgParser Inlines
613622subscript = B.subscript <$> (try $ char '_' *> maybeGroupedByBraces)
@@ -655,6 +664,21 @@ mathStringBetween c = try $ do
655664 final <- mathEnd c
656665 return $ body ++ [final]
657666
667+-- | Parse a single character between @c@ using math rules
668+math1CharBetween :: Char
669+ -> OrgParser String
670+math1CharBetween c = try $ do
671+ char c
672+ res <- noneOf $ c:mathForbiddenBorderChars
673+ char c
674+ eof <|> lookAhead (oneOf mathPostChars) *> return ()
675+ return [res]
676+
677+rawMathBetween :: String
678+ -> String
679+ -> OrgParser String
680+rawMathBetween s e = try $ string s *> manyTill anyChar (try $ string e)
681+
658682-- | Parses the start (opening character) of emphasis
659683emphasisStart :: Char -> OrgParser Char
660684emphasisStart c = try $ do
@@ -747,7 +771,7 @@ emphasisAllowedNewlines = 1
747771
748772-- | Chars allowed after an inline ($...$) math statement
749773mathPostChars :: [Char]
750−mathPostChars = "\t\n \"',-.:;?"
774+mathPostChars = "\t\n \"'),-.:;?"
751775
752776-- | Chars not allowed at the (inner) border of math
753777mathForbiddenBorderChars :: [Char]
tests/Tests/Readers/Org.hs+30−6
@@ -54,14 +54,26 @@ tests =
5454 "=Robot.rock()=" =?>
5555 para (code "Robot.rock()")
5656
57− , "Math" =:
58− "$E=mc^2$" =?>
59− para (math "E=mc^2")
60−
6157 , "Verbatim" =:
6258 "~word for word~" =?>
6359 para (rawInline "" "word for word")
6460
61+ , "Math $..$" =:
62+ "$E=mc^2$" =?>
63+ para (math "E=mc^2")
64+
65+ , "Math $$..$$" =:
66+ "$$E=mc^2$$" =?>
67+ para (displayMath "E=mc^2")
68+
69+ , "Math \\[..\\]" =:
70+ "\\[E=ℎν\\]" =?>
71+ para (displayMath "E=ℎν")
72+
73+ , "Math \\(..\\)" =:
74+ "\\(σ_x σ_p ≥ \\frac{ℏ}{2}\\)" =?>
75+ para (math "σ_x σ_p ≥ \\frac{ℏ}{2}")
76+
6577 , "Symbol" =:
6678 "A * symbol" =?>
6779 para (str "A" <> space <> str "*" <> space <> "symbol")
@@ -86,14 +98,19 @@ tests =
8698 unlines [ "this+that+ +so+on"
8799 , "seven*eight* nine*"
88100 , "+not+funny+"
89− , "this == self"
90101 ] =?>
91102 para (spcSep [ "this+that+", "+so+on"
92103 , "seven*eight*", "nine*"
93104 , strikeout "not+funny"
94− , "this" <> space <> "==" <> space <> "self"
95105 ])
96106
107+ , "No empty markup" =:
108+ -- FIXME: __ is erroneously parsed as subscript "_"
109+ -- "// ** __ ++ == ~~ $$" =?>
110+ -- para (spcSep [ "//", "**", "__", "++", "==", "~~", "$$" ])
111+ "// ** ++ == ~~ $$" =?>
112+ para (spcSep [ "//", "**", "++", "==", "~~", "$$" ])
113+
97114 , "Adherence to Org's rules for markup borders" =:
98115 "/t/& a/ / ./r/ (*l*) /e/! /b/." =?>
99116 para (spcSep [ emph $ "t/&" <> space <> "a"
@@ -109,6 +126,13 @@ tests =
109126 para ((math "a\nb\nc") <> space <>
110127 spcSep [ "$d", "e", "f", "g$" ])
111128
129+ , "Single-character math" =:
130+ "$a$ $b$! $c$?" =?>
131+ para (spcSep [ math "a"
132+ , "$b$!"
133+ , (math "c") <> "?"
134+ ])
135+
112136 , "Markup may not span more than two lines" =:
113137 unlines [ "/this *is +totally", "nice+ not*", "emph/" ] =?>
114138 para (spcSep [ "/this"