summaryrefslogtreecommitdiff
path: root/src/Text/Pandoc/Biblio.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Text/Pandoc/Biblio.hs')
-rw-r--r--src/Text/Pandoc/Biblio.hs75
1 files changed, 39 insertions, 36 deletions
diff --git a/src/Text/Pandoc/Biblio.hs b/src/Text/Pandoc/Biblio.hs
index d65c9de1c..c8e87b2a0 100644
--- a/src/Text/Pandoc/Biblio.hs
+++ b/src/Text/Pandoc/Biblio.hs
@@ -31,7 +31,7 @@ module Text.Pandoc.Biblio ( processBiblio ) where
import Data.List
import Data.Unique
-import Data.Char ( isDigit, isPunctuation )
+import Data.Char ( isDigit )
import qualified Data.Map as M
import Text.CSL hiding ( Cite(..), Citation(..) )
import qualified Text.CSL as CSL ( Cite(..) )
@@ -43,11 +43,15 @@ import Control.Monad
-- | Process a 'Pandoc' document by adding citations formatted
-- according to a CSL style, using 'citeproc' from citeproc-hs.
-processBiblio :: FilePath -> [Reference] -> Pandoc -> IO Pandoc
-processBiblio cslfile r p
+processBiblio :: FilePath -> Maybe FilePath -> [Reference] -> Pandoc
+ -> IO Pandoc
+processBiblio cslfile abrfile r p
= if null r then return p
else do
csl <- readCSLFile cslfile
+ abbrevs <- case abrfile of
+ Just f -> readJsonAbbrevFile f
+ Nothing -> return []
p' <- bottomUpM setHash p
let (nts,grps) = if styleClass csl == "note"
then let cits = queryWith getCite p'
@@ -55,29 +59,36 @@ processBiblio cslfile r p
needNt = cits \\ concat ncits
in (,) needNt $ getNoteCitations needNt p'
else (,) [] $ queryWith getCitation p'
- result = citeproc procOpts csl r (setNearNote csl $
+ style = csl { styleAbbrevs = abbrevs }
+ result = citeproc procOpts style r (setNearNote style $
map (map toCslCite) grps)
cits_map = M.fromList $ zip grps (citations result)
- biblioList = map (renderPandoc' csl) (bibliography result)
- Pandoc m b = bottomUp (procInlines $ processCite csl cits_map) p'
+ biblioList = map (renderPandoc' style) (bibliography result)
+ Pandoc m b = bottomUp (procInlines $ processCite style cits_map) p'
return . generateNotes nts . Pandoc m $ b ++ biblioList
-- | Substitute 'Cite' elements with formatted citations.
processCite :: Style -> M.Map [Citation] [FormattedOutput] -> [Inline] -> [Inline]
+processCite s cs (Cite t _ : rest) =
+ case M.lookup t cs of
+ Just (x:xs) ->
+ if isTextualCitation t
+ then renderPandoc s [x] ++
+ if null xs
+ then processCite s cs rest
+ else [Space, Cite t (renderPandoc s xs)]
+ ++ processCite s cs rest
+ else Cite t (renderPandoc s (x:xs)) : processCite s cs rest
+ _ -> Str ("Error processing " ++ show t) : processCite s cs rest
+processCite s cs (x:xs) = x : processCite s cs xs
processCite _ _ [] = []
-processCite s cs (i:is)
- | Cite t _ <- i = process t ++ processCite s cs is
- | otherwise = i : processCite s cs is
- where
- addNt t x = if null x then [] else [Cite t $ renderPandoc s x]
- process t = case M.lookup t cs of
- Just x -> if isTextualCitation t && x /= []
- then renderPandoc s [head x] ++
- if tail x /= []
- then Space : addNt t (tail x)
- else []
- else [Cite t $ renderPandoc s x]
- Nothing -> [Str ("Error processing " ++ show t)]
+
+procInlines :: ([Inline] -> [Inline]) -> Block -> Block
+procInlines f b
+ | Plain inls <- b = Plain $ f inls
+ | Para inls <- b = Para $ f inls
+ | Header i inls <- b = Header i $ f inls
+ | otherwise = b
isTextualCitation :: [Citation] -> Bool
isTextualCitation (c:_) = citationMode c == AuthorInText
@@ -112,13 +123,6 @@ setHash (Citation i p s cm nn _)
generateNotes :: [Inline] -> Pandoc -> Pandoc
generateNotes needNote = bottomUp (mvCiteInNote needNote)
-procInlines :: ([Inline] -> [Inline]) -> Block -> Block
-procInlines f b
- | Plain inls <- b = Plain $ f inls
- | Para inls <- b = Para $ f inls
- | Header i inls <- b = Header i $ f inls
- | otherwise = b
-
mvCiteInNote :: [Inline] -> Block -> Block
mvCiteInNote is = procInlines mvCite
where
@@ -143,9 +147,8 @@ mvCiteInNote is = procInlines mvCite
| otherwise = toCapital (i ++ [Str "."])
checkPt i
- | Cite c o : xs <- i
- , endWithPunct o, startWithPunct xs
- , endWithPunct o = Cite c (initInline o) : checkPt xs
+ | Cite c o : xs <- i , endWithPunct o, startWithPunct xs
+ = Cite c (initInline o) : checkPt xs
| x:xs <- i = x : checkPt xs
| otherwise = []
checkNt = bottomUp $ procInlines checkPt
@@ -165,13 +168,9 @@ toCslCite c
AuthorInText -> (True, False)
SuppressAuthor -> (False,True )
NormalCitation -> (False,False)
- s' = case s of
- [] -> []
- (Str (y:_) : _) | isPunctuation y -> s
- _ -> Str "," : Space : s
in emptyCite { CSL.citeId = citationId c
, CSL.citePrefix = PandocText $ citationPrefix c
- , CSL.citeSuffix = PandocText $ s'
+ , CSL.citeSuffix = PandocText $ s
, CSL.citeLabel = la
, CSL.citeLocator = lo
, CSL.citeNoteNumber = show $ citationNoteNum c
@@ -182,9 +181,13 @@ toCslCite c
locatorWords :: [Inline] -> (String, [Inline])
locatorWords inp =
- case parse pLocatorWords "suffix" inp of
+ case parse pLocatorWords "suffix" $ breakup inp of
Right r -> r
Left _ -> ("",inp)
+ where breakup [] = []
+ breakup (Str x : xs) = map Str (splitup x) ++ breakup xs
+ breakup (x : xs) = x : breakup xs
+ splitup = groupBy (\x y -> x /= '\160' && y /= '\160')
pLocatorWords :: GenParser Inline st (String, [Inline])
pLocatorWords = do
@@ -201,7 +204,7 @@ pMatch condition = try $ do
return t
pSpace :: GenParser Inline st Inline
-pSpace = pMatch (== Space)
+pSpace = pMatch (\t -> t == Space || t == Str "\160")
pLocator :: GenParser Inline st String
pLocator = try $ do