git.iko.soy/typeable/pandoc
on master help sign in
Org reader: Support more inline/display math variants
1715d7cAlbert Krewinkel
src/Text/Pandoc/Readers/Org.hs+26−2
@@ -512,6 +512,7 @@ inline =
512 , underline
512 , underline
513 , code
513 , code
514 , math
514 , math
515+ , displayMath
515 , verbatim
516 , verbatim
516 , subscript
517 , subscript
517 , superscript
518 , superscript
@@ -607,7 +608,15 @@ verbatim :: OrgParser Inlines
607verbatim = B.rawInline "" <$> verbatimBetween '~'
608verbatim = B.rawInline "" <$> verbatimBetween '~'
608
609
609math :: OrgParser Inlines
610math :: OrgParser Inlines
611+math = B.math <$> choice [ math1CharBetween '$'
610−math = B.math <$> mathStringBetween '$'
612+ , mathStringBetween '$'
613+ , rawMathBetween "\\(" "\\)"
614+ ]
615+
616+displayMath :: OrgParser Inlines
617+displayMath = B.displayMath <$> choice [ rawMathBetween "\\[" "\\]"
618+ , rawMathBetween "$$" "$$"
619+ ]
611
620
612subscript :: OrgParser Inlines
621subscript :: OrgParser Inlines
613subscript = B.subscript <$> (try $ char '_' *> maybeGroupedByBraces)
622subscript = B.subscript <$> (try $ char '_' *> maybeGroupedByBraces)
@@ -655,6 +664,21 @@ mathStringBetween c = try $ do
655 final <- mathEnd c
664 final <- mathEnd c
656 return $ body ++ [final]
665 return $ body ++ [final]
657
666
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+
658-- | Parses the start (opening character) of emphasis
682-- | Parses the start (opening character) of emphasis
659emphasisStart :: Char -> OrgParser Char
683emphasisStart :: Char -> OrgParser Char
660emphasisStart c = try $ do
684emphasisStart c = try $ do
@@ -747,7 +771,7 @@ emphasisAllowedNewlines = 1
747
771
748-- | Chars allowed after an inline ($...$) math statement
772-- | Chars allowed after an inline ($...$) math statement
749mathPostChars :: [Char]
773mathPostChars :: [Char]
750−mathPostChars = "\t\n \"',-.:;?"
774+mathPostChars = "\t\n \"'),-.:;?"
751
775
752-- | Chars not allowed at the (inner) border of math
776-- | Chars not allowed at the (inner) border of math
753mathForbiddenBorderChars :: [Char]
777mathForbiddenBorderChars :: [Char]
tests/Tests/Readers/Org.hs+30−6
@@ -54,14 +54,26 @@ tests =
54 "=Robot.rock()=" =?>
54 "=Robot.rock()=" =?>
55 para (code "Robot.rock()")
55 para (code "Robot.rock()")
56
56
57− , "Math" =:
58− "$E=mc^2$" =?>
59− para (math "E=mc^2")
60−
61 , "Verbatim" =:
57 , "Verbatim" =:
62 "~word for word~" =?>
58 "~word for word~" =?>
63 para (rawInline "" "word for word")
59 para (rawInline "" "word for word")
64
60
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+
65 , "Symbol" =:
77 , "Symbol" =:
66 "A * symbol" =?>
78 "A * symbol" =?>
67 para (str "A" <> space <> str "*" <> space <> "symbol")
79 para (str "A" <> space <> str "*" <> space <> "symbol")
@@ -86,14 +98,19 @@ tests =
86 unlines [ "this+that+ +so+on"
98 unlines [ "this+that+ +so+on"
87 , "seven*eight* nine*"
99 , "seven*eight* nine*"
88 , "+not+funny+"
100 , "+not+funny+"
89− , "this == self"
90 ] =?>
101 ] =?>
91 para (spcSep [ "this+that+", "+so+on"
102 para (spcSep [ "this+that+", "+so+on"
92 , "seven*eight*", "nine*"
103 , "seven*eight*", "nine*"
93 , strikeout "not+funny"
104 , strikeout "not+funny"
94− , "this" <> space <> "==" <> space <> "self"
95 ])
105 ])
96
106
107+ , "No empty markup" =:
108+ -- FIXME: __ is erroneously parsed as subscript "_"
109+ -- "// ** __ ++ == ~~ $$" =?>
110+ -- para (spcSep [ "//", "**", "__", "++", "==", "~~", "$$" ])
111+ "// ** ++ == ~~ $$" =?>
112+ para (spcSep [ "//", "**", "++", "==", "~~", "$$" ])
113+
97 , "Adherence to Org's rules for markup borders" =:
114 , "Adherence to Org's rules for markup borders" =:
98 "/t/& a/ / ./r/ (*l*) /e/! /b/." =?>
115 "/t/& a/ / ./r/ (*l*) /e/! /b/." =?>
99 para (spcSep [ emph $ "t/&" <> space <> "a"
116 para (spcSep [ emph $ "t/&" <> space <> "a"
@@ -109,6 +126,13 @@ tests =
109 para ((math "a\nb\nc") <> space <>
126 para ((math "a\nb\nc") <> space <>
110 spcSep [ "$d", "e", "f", "g$" ])
127 spcSep [ "$d", "e", "f", "g$" ])
111
128
129+ , "Single-character math" =:
130+ "$a$ $b$! $c$?" =?>
131+ para (spcSep [ math "a"
132+ , "$b$!"
133+ , (math "c") <> "?"
134+ ])
135+
112 , "Markup may not span more than two lines" =:
136 , "Markup may not span more than two lines" =:
113 unlines [ "/this *is +totally", "nice+ not*", "emph/" ] =?>
137 unlines [ "/this *is +totally", "nice+ not*", "emph/" ] =?>
114 para (spcSep [ "/this"
138 para (spcSep [ "/this"