aboutsummaryrefslogtreecommitdiff
path: root/src/Text
diff options
context:
space:
mode:
authorAlbert Krewinkel <tarleb@moltkeplatz.de>2014-04-11 11:05:42 +0200
committerAlbert Krewinkel <tarleb@moltkeplatz.de>2014-04-11 11:05:42 +0200
commit6f19be7d40f583ee4e10fa2b0f20bd4f1fa80c43 (patch)
tree04363183f1d9f3e91d65465c52ea4a9f9532bfff /src/Text
parentca40acea5b022d6309a36000d54844a482c14555 (diff)
downloadpandoc-6f19be7d40f583ee4e10fa2b0f20bd4f1fa80c43.tar.gz
Org reader: Fix parsing of sub-/superscript expressions
This fixes the org-reader's handling of sub- and superscript expressions. Simple expressions (like `2^+10`), expressions in parentheses (`a_(n+1)`) and nested sexp (like `a_(nested()parens)`) are now read correctly.
Diffstat (limited to 'src/Text')
-rw-r--r--src/Text/Pandoc/Readers/Org.hs47
1 files changed, 37 insertions, 10 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]