git.iko.soy/typeable/pandoc
on master help sign in
Org reader: support Pandocs citation extension

Citations are defined via the "normal citation" syntax used in markdown, with the sole difference that newlines are not allowed between "[...]". This is for consistency, as org-mode generally disallows newlines between square brackets. The extension is turned on by default and can be turned off via the default syntax-extension mechanism, i.e. by specifying "org-citation" as the input format. Move `citeKey` from Readers.Markdown into Parsing The function can be used by other readers, so it is made accessible for all parsers.

commitceeb701c254c6dc4c054e10dd151d9ef6f751ad7 authorAlbert Krewinkel <tarleb@moltkeplatz.de> dateWed 14 May 2014, 14:49 (12 years ago) parent2423f9e
3 files changed+76−3
src/Text/Pandoc.hs+1−1 src/Text/Pandoc/Readers/Org.hs+53−2 tests/Tests/Readers/Org.hs+22
src/Text/Pandoc.hs+1−1
@@ -275,6 +275,7 @@ getDefaultExtensions "markdown_mmd" = multimarkdownExtensions
275275getDefaultExtensions "markdown_github" = githubMarkdownExtensions
276276getDefaultExtensions "markdown" = pandocExtensions
277277getDefaultExtensions "plain" = pandocExtensions
278+getDefaultExtensions "org" = Set.fromList [Ext_citations]
278279getDefaultExtensions "textile" = Set.fromList [Ext_auto_identifiers, Ext_raw_tex]
279280getDefaultExtensions _ = Set.fromList [Ext_auto_identifiers]
280281
@@ -319,4 +320,3 @@ readJSON _ = either error id . eitherDecode' . UTF8.fromStringLazy
319320
320321writeJSON :: WriterOptions -> Pandoc -> String
321322writeJSON _ = UTF8.toStringLazy . encode
322−
src/Text/Pandoc/Readers/Org.hs+53−2
@@ -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 '/'
tests/Tests/Readers/Org.hs+22
@@ -225,6 +225,28 @@ tests =
225225 ]
226226 )
227227 "echo 'Hello, World'")
228+
229+ , "Citation" =:
230+ "[@nonexistent]" =?>
231+ let citation = Citation
232+ { citationId = "nonexistent"
233+ , citationPrefix = []
234+ , citationSuffix = []
235+ , citationMode = NormalCitation
236+ , citationNoteNum = 0
237+ , citationHash = 0}
238+ in (para $ cite [citation] "[@nonexistent]")
239+
240+ , "Citation containing text" =:
241+ "[see @item1 p. 34-35]" =?>
242+ let citation = Citation
243+ { citationId = "item1"
244+ , citationPrefix = [Str "see"]
245+ , citationSuffix = [Space ,Str "p.",Space,Str "34-35"]
246+ , citationMode = NormalCitation
247+ , citationNoteNum = 0
248+ , citationHash = 0}
249+ in (para $ cite [citation] "[see @item1 p. 34-35]")
228250 ]
229251
230252 , testGroup "Meta Information" $