git.iko.soy/typeable/pandoc
on master help sign in
Added support for latex cite commands in latex reader.
commitc2d3796439d56dff6c72e9b961d080a52cf634b9 authorNathan Gass <gass@search.ch> dateMon 13 Dec 2010, 21:32 (16 years ago) parente8679c0
2 files changed+113−12
src/Text/Pandoc/Readers/LaTeX.hs+109−8 tests/latex-reader.native+4−4
src/Text/Pandoc/Readers/LaTeX.hs+109−8
@@ -38,7 +38,7 @@ import Text.Pandoc.Definition
3838import Text.Pandoc.Shared
3939import Text.Pandoc.Parsing
4040import Data.Maybe ( fromMaybe )
41−import Data.Char ( chr )
41+import Data.Char ( chr, toUpper )
4242import Data.List ( isPrefixOf, isSuffixOf )
4343import Control.Monad ( when )
4444
@@ -50,7 +50,7 @@ readLaTeX = readWith parseLaTeX
5050
5151-- characters with special meaning
5252specialChars :: [Char]
53−specialChars = "\\`$%^&_~#{}\n \t|<>'\"-"
53+specialChars = "\\`$%^&_~#{}[]\n \t|<>'\"-"
5454
5555--
5656-- utility functions
@@ -150,7 +150,7 @@ block = choice [ hrule
150150 , header
151151 , list
152152 , blockQuote
153− , comment
153+ , commentBlock
154154 , bibliographic
155155 , para
156156 , itemBlock
@@ -433,11 +433,10 @@ unknownCommand = try $ do
433433 else return $ Plain [Str $ concat args]
434434
435435commandsToIgnore :: [String]
436−commandsToIgnore = ["special","pdfannot","pdfstringdef"]
436+commandsToIgnore = ["special","pdfannot","pdfstringdef","bibliography"]
437437
438−-- latex comment
439−comment :: GenParser Char st Block
440−comment = try $ char '%' >> manyTill anyChar newline >> spaces >> return Null
438+commentBlock :: GenParser Char st Block
439+commentBlock = comment >> return Null
441440
442441--
443442-- inline
@@ -469,12 +468,19 @@ inline = choice [ str
469468 , linebreak
470469 , accentedChar
471470 , nonbreakingSpace
471+ , cite
472472 , specialChar
473473 , rawLaTeXInline'
474474 , escapedChar
475475 , unescapedChar
476+ , comment
476477 ] <?> "inline"
477478
479+
480+-- latex comment
481+comment :: GenParser Char st Inline
482+comment = try $ char '%' >> manyTill anyChar newline >> spaces >> return (Str "")
483+
478484accentedChar :: GenParser Char st Inline
479485accentedChar = normalAccentedChar <|> specialAccentedChar
480486
@@ -564,7 +570,7 @@ escapedChar = do
564570
565571-- nonescaped special characters
566572unescapedChar :: GenParser Char st Inline
567−unescapedChar = oneOf "`$^&_#{}|<>" >>= return . (\c -> Str [c])
573+unescapedChar = oneOf "`$^&_#{}[]|<>" >>= return . (\c -> Str [c])
568574
569575specialChar :: GenParser Char st Inline
570576specialChar = choice [ spacer, interwordSpace,
@@ -788,6 +794,101 @@ footnote = try $ do
788794 setInput rest
789795 return $ Note blocks
790796
797+-- | citations
798+cite :: GenParser Char ParserState Inline
799+cite = simpleCite <|> complexNatbibCites
800+
801+simpleCiteArgs :: GenParser Char ParserState [Citation]
802+simpleCiteArgs = try $ do
803+ first <- optionMaybe $ (char '[') >> manyTill inline (char ']')
804+ second <- optionMaybe $ (char '[') >> manyTill inline (char ']')
805+ char '{'
806+ keys <- many1Till citationLabel (char '}')
807+ let (pre, suf) = case (first , second ) of
808+ (Just s , Nothing) -> ([], s )
809+ (Just s , Just t ) -> (s , t )
810+ _ -> ([], [])
811+ conv k = Citation { citationId = k
812+ , citationPrefix = []
813+ , citationSuffix = []
814+ , citationMode = NormalCitation
815+ , citationHash = 0
816+ , citationNoteNum = 0
817+ }
818+ return $ addPrefix pre $ addSuffix suf $ map conv keys
819+
820+
821+simpleCite :: GenParser Char ParserState Inline
822+simpleCite = try $ do
823+ char '\\'
824+ let biblatex = [a ++ "cite" | a <- ["auto", "foot", "paren", "super", ""]]
825+ ++ ["footcitetext"]
826+ normal = ["cite" ++ a ++ b | a <- ["al", ""], b <- ["p", "p*", ""]]
827+ ++ biblatex
828+ supress = ["citeyearpar", "citeyear", "autocite*", "cite*", "parencite*"]
829+ intext = ["textcite"] ++ ["cite" ++ a ++ b | a <- ["al", ""], b <- ["t", "t*"]]
830+ mintext = ["textcites"]
831+ mnormal = map (++ "s") biblatex
832+ cmdend = notFollowedBy (letter <|> char '*')
833+ addUpper xs = xs ++ map (\(c:cs) -> toUpper c : cs) xs
834+ toparser l t = try $ oneOfStrings (addUpper l) >> cmdend >> return t
835+ (mode, multi) <- toparser normal (NormalCitation, False)
836+ <|> toparser supress (SuppressAuthor, False)
837+ <|> toparser intext (AuthorInText , False)
838+ <|> toparser mnormal (NormalCitation, True )
839+ <|> toparser mintext (AuthorInText , True )
840+ cits <- if multi then
841+ many1 simpleCiteArgs
842+ else
843+ simpleCiteArgs >>= \c -> return [c]
844+ let (c:cs) = concat cits
845+ cits' = case mode of
846+ AuthorInText -> c {citationMode = mode} : cs
847+ _ -> map (\a -> a {citationMode = mode}) (c:cs)
848+ return $ Cite cits' []
849+
850+complexNatbibCites :: GenParser Char ParserState Inline
851+complexNatbibCites = complexNatbibTextual <|> complexNatbibParenthetical
852+
853+complexNatbibTextual :: GenParser Char ParserState Inline
854+complexNatbibTextual = try $ do
855+ string "\\citeauthor{"
856+ manyTill (noneOf "}") (char '}')
857+ skipSpaces
858+ Cite (c:cs) _ <- complexNatbibParenthetical
859+ return $ Cite (c {citationMode = AuthorInText} : cs) []
860+
861+
862+complexNatbibParenthetical :: GenParser Char ParserState Inline
863+complexNatbibParenthetical = try $ do
864+ string "\\citetext{"
865+ cits <- many1Till parseOne (char '}')
866+ return $ Cite (concat cits) []
867+ where
868+ parseOne = do
869+ skipSpaces
870+ pref <- many (notFollowedBy (oneOf "\\}") >> inline)
871+ (Cite cites _) <- simpleCite
872+ suff <- many (notFollowedBy (oneOf "\\};") >> inline)
873+ skipSpaces
874+ optional $ char ';'
875+ return $ addPrefix pref $ addSuffix suff $ cites
876+
877+addPrefix :: [Inline] -> [Citation] -> [Citation]
878+addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
879+addPrefix _ _ = []
880+
881+addSuffix :: [Inline] -> [Citation] -> [Citation]
882+addSuffix s ks@(_:_) = let k = last ks
883+ in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
884+addSuffix _ _ = []
885+
886+citationLabel :: GenParser Char ParserState String
887+citationLabel = do
888+ res <- many1 $ noneOf ",}"
889+ optional $ char ','
890+ return $ removeLeadingTrailingSpace res
891+
791892-- | Parse any LaTeX inline command and return it in a raw TeX inline element.
792893rawLaTeXInline' :: GenParser Char ParserState Inline
793894rawLaTeXInline' = do
tests/latex-reader.native+4−4
@@ -272,7 +272,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
272272, HorizontalRule
273273, Header 1 [Str "LaTeX"]
274274, BulletList
275− [ [ Para [TeX "\\cite[22-23]{smith.1899}"] ]
275+ [ [ Para [Cite [Citation {citationId = "smith.1899", citationPrefix = [], citationSuffix = [Str "22",Str "-",Str "23"], citationMode = NormalCitation, citationNoteNum = 0, citationHash = 0}] []] ]
276276 , [ Para [TeX "\\doublespacing"] ]
277277 , [ Para [Math InlineMath "2+2=4"] ]
278278 , [ Para [Math InlineMath "x \\in y"] ]
@@ -334,12 +334,12 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
334334, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
335335, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
336336, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
337−, Para [Str "With",Space,Link [Str "embedded",Space,Str "[brackets]"] ("/url/",""),Str "."]
337+, Para [Str "With",Space,Link [Str "embedded",Space,Str "[",Str "brackets",Str "]"] ("/url/",""),Str "."]
338338, Para [Link [Str "b"] ("/url/",""),Space,Str "by",Space,Str "itself",Space,Str "should",Space,Str "be",Space,Str "a",Space,Str "link."]
339339, Para [Str "Indented",Space,Link [Str "once"] ("/url",""),Str "."]
340340, Para [Str "Indented",Space,Link [Str "twice"] ("/url",""),Str "."]
341341, Para [Str "Indented",Space,Link [Str "thrice"] ("/url",""),Str "."]
342−, Para [Str "This",Space,Str "should",Space,Str "[not][]",Space,Str "be",Space,Str "a",Space,Str "link."]
342+, Para [Str "This",Space,Str "should",Space,Str "[",Str "not",Str "]",Str "[",Str "]",Space,Str "be",Space,Str "a",Space,Str "link."]
343343, CodeBlock ("",[],[]) "[not]: /url"
344344, Para [Str "Foo",Space,Link [Str "bar"] ("/url/",""),Str "."]
345345, Para [Str "Foo",Space,Link [Str "biz"] ("/url/",""),Str "."]
@@ -367,7 +367,7 @@ Pandoc (Meta {docTitle = [Str "Pandoc",Space,Str "Test",Space,Str "Suite"], docA
367367, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "movie",Space,Image [Str "image"] ("movie.jpg",""),Space,Str "icon."]
368368, HorizontalRule
369369, Header 1 [Str "Footnotes"]
370−, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.[",Str "^",Str "my",Space,Str "note]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[bracketed",Space,Str "text]."]]]
370+, Para [Str "Here",Space,Str "is",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Note [Para [Str "Here",Space,Str "is",Space,Str "the",Space,Str "footnote.",Space,Str "It",Space,Str "can",Space,Str "go",Space,Str "anywhere",Space,Str "after",Space,Str "the",Space,Str "footnote",Space,Str "reference.",Space,Str "It",Space,Str "need",Space,Str "not",Space,Str "be",Space,Str "placed",Space,Str "at",Space,Str "the",Space,Str "end",Space,Str "of",Space,Str "the",Space,Str "document."]],Space,Str "and",Space,Str "another.",Note [Para [Str "Here",Apostrophe,Str "s",Space,Str "the",Space,Str "long",Space,Str "note.",Space,Str "This",Space,Str "one",Space,Str "contains",Space,Str "multiple",Space,Str "blocks."],Para [Str "Subsequent",Space,Str "blocks",Space,Str "are",Space,Str "indented",Space,Str "to",Space,Str "show",Space,Str "that",Space,Str "they",Space,Str "belong",Space,Str "to",Space,Str "the",Space,Str "footnote",Space,Str "(as",Space,Str "with",Space,Str "list",Space,Str "items)."],CodeBlock ("",[],[]) " { <code> }",Para [Str "If",Space,Str "you",Space,Str "want,",Space,Str "you",Space,Str "can",Space,Str "indent",Space,Str "every",Space,Str "line,",Space,Str "but",Space,Str "you",Space,Str "can",Space,Str "also",Space,Str "be",Space,Str "lazy",Space,Str "and",Space,Str "just",Space,Str "indent",Space,Str "the",Space,Str "first",Space,Str "line",Space,Str "of",Space,Str "each",Space,Str "block."]],Space,Str "This",Space,Str "should",Space,Emph [Str "not"],Space,Str "be",Space,Str "a",Space,Str "footnote",Space,Str "reference,",Space,Str "because",Space,Str "it",Space,Str "contains",Space,Str "a",Space,Str "space.",Str "[",Str "^",Str "my",Space,Str "note",Str "]",Space,Str "Here",Space,Str "is",Space,Str "an",Space,Str "inline",Space,Str "note.",Note [Para [Str "This",Space,Str "is",Space,Emph [Str "easier"],Space,Str "to",Space,Str "type.",Space,Str "Inline",Space,Str "notes",Space,Str "may",Space,Str "contain",Space,Link [Str "links"] ("http://google.com",""),Space,Str "and",Space,Code "]",Space,Str "verbatim",Space,Str "characters,",Space,Str "as",Space,Str "well",Space,Str "as",Space,Str "[",Str "bracketed",Space,Str "text",Str "]",Str "."]]]
371371, BlockQuote
372372 [ Para [Str "Notes",Space,Str "can",Space,Str "go",Space,Str "in",Space,Str "quotes.",Note [Para [Str "In",Space,Str "quote."]]] ]
373373