@@ -27,7 +27,7 @@ import Text.Pandoc.Error (PandocError(..))
27import Text.Pandoc.Extensions (pandocExtensions)
27import Text.Pandoc.Extensions (pandocExtensions)
28import Text.Pandoc.Logging (LogMessage(..))
28import Text.Pandoc.Logging (LogMessage(..))
29import Text.Pandoc.Options (ReaderOptions(..))
29import Text.Pandoc.Options (ReaderOptions(..))
30−import Text.Pandoc.Shared (stringify, ordNub, tshow)
30+import Text.Pandoc.Shared (stringify, ordNub, blocksToInlines, tshow)
31import qualified Text.Pandoc.UTF8 as UTF8
31import qualified Text.Pandoc.UTF8 as UTF8
32import Text.Pandoc.Walk (query, walk, walkM)
32import Text.Pandoc.Walk (query, walk, walkM)
33import Control.Applicative ((<|>))
33import Control.Applicative ((<|>))
@@ -49,7 +49,6 @@ import qualified Data.Text as T
49import System.FilePath (takeExtension)
49import System.FilePath (takeExtension)
50import Safe (lastMay, initSafe)
50import Safe (lastMay, initSafe)
53processCitations :: PandocMonad m => Pandoc -> m Pandoc
52processCitations :: PandocMonad m => Pandoc -> m Pandoc
54processCitations (Pandoc meta bs) = do
53processCitations (Pandoc meta bs) = do
55 style <- getStyle (Pandoc meta bs)
54 style <- getStyle (Pandoc meta bs)
@@ -91,18 +90,22 @@ processCitations (Pandoc meta bs) = do
91 walk (convertQuotes locale) .
90 walk (convertQuotes locale) .
92 insertSpace $ out)
91 insertSpace $ out)
93 (resultBibliography result)
92 (resultBibliography result)
94− let moveNotes = styleIsNoteStyle sopts &&
93+ let moveNotes = maybe True truish $
95− maybe True truish (lookupMeta "notes-after-punctuation" meta)
94+ lookupMeta "notes-after-punctuation" meta
96 let cits = map (walk (convertQuotes locale)) $
95 let cits = map (walk (convertQuotes locale)) $
97 resultCitations result
96 resultCitations result
98+ let fixQuotes = case localePunctuationInQuote locale of
100+ B.toList . movePunctuationInsideQuotes . B.fromList
99 let metanocites = lookupMeta "nocite" meta
103 let metanocites = lookupMeta "nocite" meta
100 let Pandoc meta'' bs' =
104 let Pandoc meta'' bs' =
101 maybe id (setMeta "nocite") metanocites .
105 maybe id (setMeta "nocite") metanocites .
106+ walk (map capitalizeNoteCitation .
102− walk (mvPunct moveNotes locale) .
107+ fixQuotes . mvPunct moveNotes locale) .
103− (if styleIsNoteStyle sopts
104− then walk addNote . walk deNote
108+ walk deNote .
106 evalState (walkM insertResolvedCitations $ Pandoc meta' bs)
109 evalState (walkM insertResolvedCitations $ Pandoc meta' bs)
108 return $ Pandoc meta''
111 return $ Pandoc meta''
@@ -372,6 +375,7 @@ formatFromExtension fp = case dropWhile (== '.') $ takeExtension fp of
374isNote :: Inline -> Bool
377isNote :: Inline -> Bool
378+isNote (Note _) = True
375isNote (Cite _ [Note _]) = True
379isNote (Cite _ [Note _]) = True
376 -- the following allows citation styles that are "in-text" but use superscript
380 -- the following allows citation styles that are "in-text" but use superscript
377 -- references to be treated as if they are "notes" for the purposes of moving
381 -- references to be treated as if they are "notes" for the purposes of moving
@@ -384,12 +388,6 @@ isSpacy Space = True
384isSpacy SoftBreak = True
388isSpacy SoftBreak = True
385isSpacy _ = False
389isSpacy _ = False
387−movePunctInsideQuotes :: Locale -> [Inline] -> [Inline]
388−movePunctInsideQuotes locale
389− | localePunctuationInQuote locale == Just True
390− = B.toList . movePunctuationInsideQuotes . B.fromList
394mvPunct :: Bool -> Locale -> [Inline] -> [Inline]
392mvPunct :: Bool -> Locale -> [Inline] -> [Inline]
395mvPunct moveNotes locale (x : xs)
393mvPunct moveNotes locale (x : xs)
@@ -402,8 +400,7 @@ mvPunct moveNotes locale (q : s : x : ys)
402 in if moveNotes
400 in if moveNotes
403 then if T.null spunct
401 then if T.null spunct
404 then q : x : mvPunct moveNotes locale ys
402 then q : x : mvPunct moveNotes locale ys
405− else movePunctInsideQuotes locale
406− [q , Str spunct , x] ++ mvPunct moveNotes locale
403+ else q : Str spunct : x : mvPunct moveNotes locale
407 (B.toList
404 (B.toList
408 (dropTextWhile isPunctuation (B.fromList ys)))
405 (dropTextWhile isPunctuation (B.fromList ys)))
409 else q : x : mvPunct moveNotes locale ys
406 else q : x : mvPunct moveNotes locale ys
@@ -415,10 +412,9 @@ mvPunct moveNotes locale (Cite cs ils : ys)
415 , moveNotes
412 , moveNotes
416 = let s = stringify ys
413 = let s = stringify ys
417 spunct = T.takeWhile isPunctuation s
414 spunct = T.takeWhile isPunctuation s
418− in Cite cs (movePunctInsideQuotes locale $
419− init ils
415+ in Cite cs (init ils
420− ++ [Str spunct | not (endWithPunct False (init ils))]
416+ ++ [Str spunct | not (endWithPunct False (init ils))]
421− ++ [last ils]) :
417+ ++ [last ils]) :
422 mvPunct moveNotes locale
418 mvPunct moveNotes locale
423 (B.toList (dropTextWhile isPunctuation (B.fromList ys)))
419 (B.toList (dropTextWhile isPunctuation (B.fromList ys)))
424mvPunct moveNotes locale (s : x : ys) | isSpacy s, isNote x =
420mvPunct moveNotes locale (s : x : ys) | isSpacy s, isNote x =
@@ -564,62 +560,42 @@ extractText (FancyVal x) = toText x
564extractText (NumVal n) = T.pack (show n)
560extractText (NumVal n) = T.pack (show n)
565extractText _ = mempty
561extractText _ = mempty
567−-- Here we take the Spans with class csl-note that are left
568−-- after deNote has removed nested ones, and convert them
570−addNote :: Inline -> Inline
563+capitalizeNoteCitation :: Inline -> Inline
571−addNote (Span ("",["csl-note"],[]) ils) =
564+capitalizeNoteCitation (Cite cs [Note [Para ils]]) =
572− Note [Para $
565+ Cite cs
573− B.toList . addTextCase Nothing CapitalizeFirst . B.fromList $ ils]
566+ [Note [Para $ B.toList $ addTextCase Nothing CapitalizeFirst
574−addNote x = x
567+ $ B.fromList ils]]
575−
568+capitalizeNoteCitation x = x
576−-- Here we handle citation notes that occur inside footnotes
569+
577−-- or other citation notes, in a note style. We don't want
578−-- notes inside notes, so we convert these to parenthesized
579−-- or comma-separated citations.
580−deNote :: Inline -> Inline
570+deNote :: [Inline] -> [Inline]
581−deNote (Note bs) =
571+deNote [] = []
582− case bs of
572+deNote (Note bs:rest) =
583− [Para (cit@(Cite (c:_) _) : ils)]
573+ Note (walk go bs) : deNote rest
584− | citationMode c /= AuthorInText ->
585− -- if citation is first in note, no need to parenthesize.
586− Note [Para (walk removeNotes $ cit : walk addParens ils)]
587− _ -> Note (walk removeNotes . walk addParens $ bs)
590− addParens [] = []
575+ go [] = []
591− addParens (Cite (c:cs) ils : zs)
576+ go (Cite (c:cs) ils : zs)
592 | citationMode c == AuthorInText
577 | citationMode c == AuthorInText
593− = Cite (c:cs) (concatMap (noteAfterComma (needsPeriod zs)) ils) :
578+ = Cite (c:cs) (concatMap (noteAfterComma (needsPeriod zs)) ils) : go zs
595 | otherwise
579 | otherwise
596− = Cite (c:cs) (concatMap noteInParens ils) : addParens zs
580+ = Cite (c:cs) (concatMap noteInParens ils) : go zs
597− addParens (x:xs) = x : addParens xs
581+ go (x:xs) = x : go xs
599− removeNotes (Span ("",["csl-note"],[]) ils) = Span ("",[],[]) ils
602 needsPeriod [] = True
582 needsPeriod [] = True
603 needsPeriod (Str t:_) = case T.uncons t of
583 needsPeriod (Str t:_) = case T.uncons t of
604 Nothing -> False
584 Nothing -> False
605 Just (c,_) -> isUpper c
585 Just (c,_) -> isUpper c
606 needsPeriod (Space:zs) = needsPeriod zs
586 needsPeriod (Space:zs) = needsPeriod zs
607 needsPeriod _ = False
587 needsPeriod _ = False
609− noteInParens (Span ("",["csl-note"],[]) ils)
588+ noteInParens (Note bs')
610 = Space : Str "(" :
589 = Space : Str "(" :
611− removeFinalPeriod ils ++ [Str ")"]
590+ removeFinalPeriod (blocksToInlines bs') ++ [Str ")"]
612 noteInParens x = [x]
591 noteInParens x = [x]
614− noteAfterComma needsPer (Span ("",["csl-note"],[]) ils)
592+ noteAfterComma needsPer (Note bs')
616 = Str "," : Space :
593 = Str "," : Space :
617− if needsPer
594+ (if needsPer
618− then ils
595+ then id
619− else removeFinalPeriod ils
596+ else removeFinalPeriod) (blocksToInlines bs')
620 noteAfterComma _ x = [x]
597 noteAfterComma _ x = [x]
622−deNote x = x
598+deNote (x:xs) = x : deNote xs
624-- Note: we can't use dropTextWhileEnd indiscriminately,
600-- Note: we can't use dropTextWhileEnd indiscriminately,
625-- because this would remove the final period on abbreviations like Ibid.
601-- because this would remove the final period on abbreviations like Ibid.