@@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 Copyright : Copyright (C) 2008 Andrea Rossato
22 Copyright : Copyright (C) 2008 Andrea Rossato
23 License : GNU GPL, version 2 or above
23 License : GNU GPL, version 2 or above
25− Maintainer : Andrea Rossato <andrea.rossato@ing.unitn.it>
25+ Maintainer : Andrea Rossato <andrea.rossato@unitn.it>
26 Stability : alpha
26 Stability : alpha
27 Portability : portable
27 Portability : portable
@@ -31,7 +31,9 @@ module Text.Pandoc.Biblio ( processBiblio ) where
32import Control.Monad ( when )
32import Control.Monad ( when )
33import Data.List
33import Data.List
34−import Text.CSL
34+import Data.Unique
35+import Text.CSL hiding ( Cite(..), Citation(..) )
36+import qualified Text.CSL as CSL ( Cite(..) )
35import Text.Pandoc.Definition
37import Text.Pandoc.Definition
37-- | Process a 'Pandoc' document by adding citations formatted
39-- | Process a 'Pandoc' document by adding citations formatted
@@ -42,25 +44,78 @@ processBiblio cf r p
43 when (null cf) $ error "Missing the needed citation style file"
45 when (null cf) $ error "Missing the needed citation style file"
44 csl <- readCSLFile cf
46 csl <- readCSLFile cf
45− let groups = queryWith getCite p
47+ p' <- if styleClass csl == "note"
49+ else processWithM setHash p
50+ let groups = if styleClass csl /= "note"
51+ then queryWith getCitation p'
52+ else getNoteCitations p'
46− result = citeproc csl r groups
53+ result = citeproc' csl r (setNearNote csl $ map (map toCslCite) groups)
47 cits_map = zip groups (citations result)
54 cits_map = zip groups (citations result)
48 biblioList = map (read . renderPandoc' csl) (bibliography result)
55 biblioList = map (read . renderPandoc' csl) (bibliography result)
49− Pandoc m b = processWith (processCite csl cits_map) p
56+ Pandoc m b = processWith (processCite csl cits_map) p'
50 return $ Pandoc m $ b ++ biblioList
57 return $ Pandoc m $ b ++ biblioList
52-- | Substitute 'Cite' elements with formatted citations.
59-- | Substitute 'Cite' elements with formatted citations.
53−processCite :: Style -> [([Target],[FormattedOutput])] -> Inline -> Inline
60+processCite :: Style -> [([Citation],[FormattedOutput])] -> Inline -> Inline
54processCite s cs il
61processCite s cs il
55 | Cite t _ <- il = Cite t (process t)
62 | Cite t _ <- il = Cite t (process t)
56 | otherwise = il
63 | otherwise = il
58− process t = case elemIndex t (map fst cs) of
65+ process t = case lookup t cs of
59− Just i -> read . renderPandoc s $ snd (cs !! i)
66+ Just i -> read $ renderPandoc s i
60 Nothing -> [Str ("Error processing " ++ show t)]
67 Nothing -> [Str ("Error processing " ++ show t)]
62-- | Retrieve all citations from a 'Pandoc' docuument. To be used with
69-- | Retrieve all citations from a 'Pandoc' docuument. To be used with
63-- 'queryWith'.
70-- 'queryWith'.
64−getCite :: Inline -> [[(String,String)]]
71+getCitation :: Inline -> [[Citation]]
65−getCite i | Cite t _ <- i = [t]
72+getCitation i | Cite t _ <- i = [t]
75+getNote :: Inline -> [Inline]
76+getNote i | Note _ <- i = [i]
79+getCite :: Inline -> [Inline]
80+getCite i | Cite _ _ <- i = [i]
66 | otherwise = []
81 | otherwise = []
83+getNoteCitations :: Pandoc -> [[Citation]]
85+ = let cits = concat . flip (zipWith $ setCiteNoteNum) [1..] .
86+ map (queryWith getCite) . queryWith getNote
87+ in queryWith getCitation . cits
89+setHash :: Citation -> IO Citation
90+setHash (Citation i p l nn ao na _)
91+ = hashUnique `fmap` newUnique >>= return . Citation i p l nn ao na
93+processNote :: Pandoc -> IO Pandoc
95+ p' <- processWithM setHash p
96+ let cits = queryWith getCite p'
97+ ncits = map (queryWith getCite) $ queryWith getNote p'
98+ needNote = cits \\ concat ncits
99+ return $ processWith (mvCiteInNote needNote) p'
101+mvCiteInNote :: [Inline] -> Inline -> Inline
102+mvCiteInNote is i = if i `elem` is then Note [Para [i]] else i
104+setCiteNoteNum :: [Inline] -> Int -> [Inline]
105+setCiteNoteNum ((Cite cs o):xs) n = Cite (setCitationNoteNum n cs) o : setCiteNoteNum xs n
106+setCiteNoteNum _ _ = []
108+setCitationNoteNum :: Int -> [Citation] -> [Citation]
109+setCitationNoteNum i = map $ \c -> c { citationNoteNum = i}
111+toCslCite :: Citation -> CSL.Cite
112+toCslCite (Citation i p l nn ao na _)
113+ = let (la,lo) = parseLocator l
114+ in emptyCite { CSL.citeId = i
115+ , CSL.citePrefix = p
116+ , CSL.citeLabel = la
117+ , CSL.citeLocator = lo
118+ , CSL.citeNoteNumber = show nn
119+ , CSL.authorOnly = ao
120+ , CSL.suppressAuthor = na