@@ -32,7 +32,7 @@ import Text.Pandoc.Definition
32import Text.Pandoc.Shared
32import Text.Pandoc.Shared
33import Text.Pandoc.Templates
33import Text.Pandoc.Templates
34import Text.Printf ( printf )
34import Text.Printf ( printf )
35−import Data.List ( (\\), isSuffixOf, isPrefixOf, intersperse )
35+import Data.List ( (\\), isSuffixOf, isPrefixOf, intersperse, intercalate )
36import Data.Char ( toLower )
36import Data.Char ( toLower )
37import Control.Monad.State
37import Control.Monad.State
38import Text.PrettyPrint.HughesPJ hiding ( Str )
38import Text.PrettyPrint.HughesPJ hiding ( Str )
@@ -76,7 +76,16 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
76 body <- blockListToLaTeX blocks
76 body <- blockListToLaTeX blocks
77 let main = render body
77 let main = render body
79+ let biblio = takeWhile ((/=) '.') $ writerBiblioFile options
80+ citecontext = case writerCiteMethod options of
81+ Natbib -> [ ("biblio", biblio)
84+ Biblatex -> [ ("biblio", biblio)
85+ , ("biblatex", "yes")
79− let context = writerVariables options ++
88+ context = writerVariables options ++
80 [ ("toc", if writerTableOfContents options then "yes" else "")
89 [ ("toc", if writerTableOfContents options then "yes" else "")
81 , ("body", main)
90 , ("body", main)
82 , ("title", titletext)
91 , ("title", titletext)
@@ -91,7 +100,8 @@ pandocToLaTeX options (Pandoc (Meta title authors date) blocks) = do
91 [ ("url", "yes") | stUrl st ] ++
100 [ ("url", "yes") | stUrl st ] ++
92 [ ("numbersections", "yes") | writerNumberSections options ] ++
101 [ ("numbersections", "yes") | writerNumberSections options ] ++
93 [ ("lhs", "yes") | stLHS st ] ++
102 [ ("lhs", "yes") | stLHS st ] ++
94− [ ("graphics", "yes") | stGraphics st ]
103+ [ ("graphics", "yes") | stGraphics st ] ++
95 return $ if writerStandalone options
105 return $ if writerStandalone options
96 then renderTemplate context template
106 then renderTemplate context template
97 else main
107 else main
@@ -298,8 +308,14 @@ inlineToLaTeX (Subscript lst) = do
298 return $ inCmd "textsubscr" contents
308 return $ inCmd "textsubscr" contents
299inlineToLaTeX (SmallCaps lst) =
309inlineToLaTeX (SmallCaps lst) =
300 inlineListToLaTeX (deVerb lst) >>= return . inCmd "textsc"
310 inlineListToLaTeX (deVerb lst) >>= return . inCmd "textsc"
301−inlineToLaTeX (Cite _ lst) =
311+inlineToLaTeX (Cite cits lst) = do
313+ let opts = stOptions st
314+ case writerCiteMethod opts of
315+ Natbib -> citationsToNatbib cits
316+ Biblatex -> citationsToBiblatex cits
302− inlineListToLaTeX lst
317+ _ -> inlineListToLaTeX lst
303inlineToLaTeX (Code str) = do
319inlineToLaTeX (Code str) = do
304 st <- get
320 st <- get
305 when (stInNote st) $ modify $ \s -> s{ stVerbInNote = True }
321 when (stInNote st) $ modify $ \s -> s{ stVerbInNote = True }
@@ -355,3 +371,95 @@ inlineToLaTeX (Note contents) = do
355 let optNewline = "\\end{Verbatim}" `isSuffixOf` rawnote
371 let optNewline = "\\end{Verbatim}" `isSuffixOf` rawnote
356 return $ text "\\footnote{" <>
372 return $ text "\\footnote{" <>
357 text rawnote <> (if optNewline then char '\n' else empty) <> char '}'
373 text rawnote <> (if optNewline then char '\n' else empty) <> char '}'
376+citationsToNatbib :: [Citation] -> State WriterState Doc
377+citationsToNatbib (one:[])
378+ = citeCommand c p s k
380+ Citation { citationId = k
381+ , citationPrefix = p
382+ , citationSuffix = s
387+ AuthorInText -> "citet"
388+ SuppressAuthor -> "citeyearpar"
389+ NormalCitation -> "citep"
391+citationsToNatbib cits
392+ | noPrefix (tail cits) && noSuffix (init cits) && ismode NormalCitation cits
393+ = citeCommand "citep" p s ks
395+ noPrefix = and . map (null . citationPrefix)
396+ noSuffix = and . map (null . citationSuffix)
397+ ismode m = and . map (((==) m) . citationMode)
398+ p = citationPrefix $ head $ cits
399+ s = citationSuffix $ last $ cits
400+ ks = intercalate ", " $ map citationId cits
402+citationsToNatbib (c:cs) | citationMode c == AuthorInText = do
403+ author <- citeCommand "citeauthor" [] [] (citationId c)
404+ cits <- citationsToNatbib (c { citationMode = SuppressAuthor } : cs)
405+ return $ author <+> cits
407+citationsToNatbib cits = do
408+ cits' <- mapM convertOne cits
409+ return $ text "\\citetext{" <> foldl combineTwo empty cits' <> text "}"
411+ combineTwo a b | isEmpty a = b
412+ | otherwise = a <> text "; " <> b
413+ convertOne Citation { citationId = k
414+ , citationPrefix = p
415+ , citationSuffix = s
419+ AuthorInText -> citeCommand "citealt" p s k
420+ SuppressAuthor -> citeCommand "citeyear" p s k
421+ NormalCitation -> citeCommand "citealp" p s k
423+citeCommand :: String -> [Inline] -> [Inline] -> String -> State WriterState Doc
424+citeCommand c p s k = do
425+ args <- citeArguments p s k
426+ return $ text ("\\" ++ c) <> args
428+citeArguments :: [Inline] -> [Inline] -> String -> State WriterState Doc
429+citeArguments p s k = do
430+ pdoc <- inlineListToLaTeX p
431+ sdoc <- inlineListToLaTeX s
432+ let optargs = case (isEmpty pdoc, isEmpty sdoc) of
433+ (True, True ) -> empty
434+ (True, False) -> brackets sdoc
435+ (_ , _ ) -> brackets pdoc <> brackets sdoc
436+ return $ optargs <> braces (text k)
438+citationsToBiblatex :: [Citation] -> State WriterState Doc
439+citationsToBiblatex (one:[])
440+ = citeCommand cmd p s k
442+ Citation { citationId = k
443+ , citationPrefix = p
444+ , citationSuffix = s
448+ SuppressAuthor -> "autocite*"
449+ AuthorInText -> "textcite"
450+ NormalCitation -> "autocite"
452+citationsToBiblatex (c:cs) = do
453+ args <- mapM convertOne (c:cs)
454+ return $ text cmd <> foldl (<>) empty args
456+ cmd = case citationMode c of
457+ AuthorInText -> "\\textcites"
459+ convertOne Citation { citationId = k
460+ , citationPrefix = p
461+ , citationSuffix = s
463+ = citeArguments p s k
465+citationsToBiblatex _ = return empty