diff options
-rw-r--r-- | src/Text/Pandoc/Readers/Org.hs | 47 | ||||
-rw-r--r-- | tests/Tests/Readers/Org.hs | 39 |
2 files changed, 67 insertions, 19 deletions
diff --git a/src/Text/Pandoc/Readers/Org.hs b/src/Text/Pandoc/Readers/Org.hs index 29611e8cc..ceac69367 100644 --- a/src/Text/Pandoc/Readers/Org.hs +++ b/src/Text/Pandoc/Readers/Org.hs @@ -622,17 +622,11 @@ displayMath = B.displayMath <$> choice [ rawMathBetween "\\[" "\\]" , rawMathBetween "$$" "$$" ] -subscript :: OrgParser Inlines -subscript = B.subscript <$> try (char '_' *> maybeGroupedByBraces) +subscript :: OrgParser Inlines +subscript = B.subscript <$> try (char '_' *> subOrSuperExpr) -superscript :: OrgParser Inlines -superscript = B.superscript <$> try (char '^' *> maybeGroupedByBraces) - -maybeGroupedByBraces :: OrgParser Inlines -maybeGroupedByBraces = try $ - choice [ try $ enclosedInlines (char '{') (char '}') - , B.str . (:"") <$> anyChar - ] +superscript :: OrgParser Inlines +superscript = B.superscript <$> try (char '^' *> subOrSuperExpr) symbol :: OrgParser Inlines symbol = B.str . (: "") <$> (oneOf specialChars >>= updatePositions) @@ -805,3 +799,36 @@ notAfterForbiddenBorderChar = do pos <- getPosition lastFBCPos <- orgStateLastForbiddenCharPos <$> getState return $ lastFBCPos /= Just pos + +-- | Read a sub- or superscript expression +subOrSuperExpr :: OrgParser Inlines +subOrSuperExpr = try $ do + choice [ balancedSexp '{' '}' + , balancedSexp '(' ')' >>= return . enclosing ('(', ')') + , simpleSubOrSuperString + ] >>= parseFromString (mconcat <$> many inline) + +-- | Read a balanced sexp +balancedSexp :: Char + -> Char + -> OrgParser String +balancedSexp l r = try $ do + char l + res <- concat <$> many ( many1 (noneOf ([l, r] ++ "\n\r")) + <|> try (string [l, r]) + <|> enclosing (l, r) <$> balancedSexp l r + ) + char r + return res + +simpleSubOrSuperString :: OrgParser String +simpleSubOrSuperString = try $ + choice [ string "*" + , mappend <$> option [] ((:[]) <$> oneOf "+-") + <*> many1 alphaNum + ] + +enclosing :: (a, a) + -> [a] + -> [a] +enclosing (left, right) s = left : s ++ [right] diff --git a/tests/Tests/Readers/Org.hs b/tests/Tests/Readers/Org.hs index 9e9482e45..49130f0ab 100644 --- a/tests/Tests/Readers/Org.hs +++ b/tests/Tests/Readers/Org.hs @@ -78,15 +78,15 @@ tests = "A * symbol" =?> para (str "A" <> space <> str "*" <> space <> "symbol") - , "Superscript single char" =: - "2^n" =?> - para (str "2" <> superscript "n") + , "Superscript simple expression" =: + "2^-λ" =?> + para (str "2" <> superscript "-λ") , "Superscript multi char" =: "2^{n-1}" =?> para (str "2" <> superscript "n-1") - , "Subscript single char" =: + , "Subscript simple expression" =: "a_n" =?> para (str "a" <> subscript "n") @@ -105,11 +105,8 @@ tests = ]) , "No empty markup" =: - -- FIXME: __ is erroneously parsed as subscript "_" - -- "// ** __ ++ == ~~ $$" =?> - -- para (spcSep [ "//", "**", "__", "++", "==", "~~", "$$" ]) - "// ** ++ == ~~ $$" =?> - para (spcSep [ "//", "**", "++", "==", "~~", "$$" ]) + "// ** __ ++ == ~~ $$" =?> + para (spcSep [ "//", "**", "__", "++", "==", "~~", "$$" ]) , "Adherence to Org's rules for markup borders" =: "/t/& a/ / ./r/ (*l*) /e/! /b/." =?> @@ -143,6 +140,30 @@ tests = ])) , "emph/" ]) + , "Sub- and superscript expressions" =: + unlines [ "a_(a(b)(c)d)" + , "e^(f(g)h)" + , "i_(jk)l)" + , "m^()n" + , "o_{p{q{}r}}" + , "s^{t{u}v}" + , "w_{xy}z}" + , "1^{}2" + , "3_{{}}" + , "4^(a(*b(c*)d))" + ] =?> + para (spcSep [ "a" <> subscript "(a(b)(c)d)" + , "e" <> superscript "(f(g)h)" + , "i" <> (subscript "(jk)") <> "l)" + , "m" <> (superscript "()") <> "n" + , "o" <> subscript "p{q{}r}" + , "s" <> superscript "t{u}v" + , "w" <> (subscript "xy") <> "z}" + , "1" <> (superscript "") <> "2" + , "3" <> subscript "{}" + , "4" <> superscript ("(a(" <> strong "b(c" <> ")d))") + ]) + , "Image" =: "[[./sunset.jpg]]" =?> (para $ image "./sunset.jpg" "" "") |