@@ -869,6 +869,7 @@ inline :: OrgParser (F Inlines)
869869inline =
870870 choice [ whitespace
871871 , linebreak
872+ , cite
872873 , footnote
873874 , linkOrImage
874875 , anchor
@@ -933,6 +934,51 @@ endline = try $ do
933934 updateLastPreCharPos
934935 return . return $ B.space
935936
937+cite :: OrgParser (F Inlines)
938+cite = try $ do
939+ guardEnabled Ext_citations
940+ (cs, raw) <- withRaw normalCite
941+ return $ (flip B.cite (B.text raw)) <$> cs
942+
943+normalCite :: OrgParser (F [Citation])
944+normalCite = try $ char '['
945+ *> skipSpaces
946+ *> citeList
947+ <* skipSpaces
948+ <* char ']'
949+
950+citeList :: OrgParser (F [Citation])
951+citeList = sequence <$> sepBy1 citation (try $ char ';' *> skipSpaces)
952+
953+citation :: OrgParser (F Citation)
954+citation = try $ do
955+ pref <- prefix
956+ (suppress_author, key) <- citeKey
957+ suff <- suffix
958+ return $ do
959+ x <- pref
960+ y <- suff
961+ return $ Citation{ citationId = key
962+ , citationPrefix = B.toList x
963+ , citationSuffix = B.toList y
964+ , citationMode = if suppress_author
965+ then SuppressAuthor
966+ else NormalCitation
967+ , citationNoteNum = 0
968+ , citationHash = 0
969+ }
970+ where
971+ prefix = trimInlinesF . mconcat <$>
972+ manyTill inline (char ']' <|> (']' <$ lookAhead citeKey))
973+ suffix = try $ do
974+ hasSpace <- option False (notFollowedBy nonspaceChar >> return True)
975+ skipSpaces
976+ rest <- trimInlinesF . mconcat <$>
977+ many (notFollowedBy (oneOf ";]") *> inline)
978+ return $ if hasSpace
979+ then (B.space <>) <$> rest
980+ else rest
981+
936982footnote :: OrgParser (F Inlines)
937983footnote = try $ inlineNote <|> referencedNote
938984
@@ -1007,7 +1053,7 @@ selfTarget :: OrgParser String
10071053selfTarget = try $ char '[' *> linkTarget <* char ']'
10081054
10091055linkTarget :: OrgParser String
1010−linkTarget = enclosed (char '[') (char ']') (noneOf "\n\r[]")
1056+linkTarget = enclosedByPair '[' ']' (noneOf "\n\r[]")
10111057
10121058applyCustomLinkFormat :: String -> OrgParser (F String)
10131059applyCustomLinkFormat link = do
@@ -1083,7 +1129,12 @@ inlineCodeBlock = try $ do
10831129 let attrClasses = [translateLang lang, rundocBlockClass]
10841130 let attrKeyVal = map toRundocAttrib (("language", lang) : opts)
10851131 returnF $ B.codeWith ("", attrClasses, attrKeyVal) inlineCode
1086− where enclosedByPair s e p = char s *> many1Till p (char e)
1132+
1133+enclosedByPair :: Char -- ^ opening char
1134+ -> Char -- ^ closing char
1135+ -> OrgParser a -- ^ parser
1136+ -> OrgParser [a]
1137+enclosedByPair s e p = char s *> many1Till p (char e)
10871138
10881139emph :: OrgParser (F Inlines)
10891140emph = fmap B.emph <$> emphasisBetween '/'