Factor out T.P.Readers.LaTeX.Citation.
This commit is contained in:
parent
08231f5cdd
commit
2faa57e8e9
4 changed files with 232 additions and 186 deletions
|
@ -631,6 +631,7 @@ library
|
||||||
Text.Pandoc.Readers.LaTeX.Lang,
|
Text.Pandoc.Readers.LaTeX.Lang,
|
||||||
Text.Pandoc.Readers.LaTeX.SIunitx,
|
Text.Pandoc.Readers.LaTeX.SIunitx,
|
||||||
Text.Pandoc.Readers.LaTeX.Accent,
|
Text.Pandoc.Readers.LaTeX.Accent,
|
||||||
|
Text.Pandoc.Readers.LaTeX.Citation,
|
||||||
Text.Pandoc.Readers.LaTeX.Table,
|
Text.Pandoc.Readers.LaTeX.Table,
|
||||||
Text.Pandoc.Readers.Odt.Base,
|
Text.Pandoc.Readers.Odt.Base,
|
||||||
Text.Pandoc.Readers.Odt.Namespaces,
|
Text.Pandoc.Readers.Odt.Namespaces,
|
||||||
|
|
|
@ -56,6 +56,7 @@ import Text.Pandoc.Readers.LaTeX.Types (ExpansionPoint (..), Macro (..),
|
||||||
ArgSpec (..), Tok (..), TokType (..))
|
ArgSpec (..), Tok (..), TokType (..))
|
||||||
import Text.Pandoc.Readers.LaTeX.Parsing
|
import Text.Pandoc.Readers.LaTeX.Parsing
|
||||||
import Text.Pandoc.Readers.LaTeX.Accent (accentCommands)
|
import Text.Pandoc.Readers.LaTeX.Accent (accentCommands)
|
||||||
|
import Text.Pandoc.Readers.LaTeX.Citation (citationCommands, cites)
|
||||||
import Text.Pandoc.Readers.LaTeX.Table (tableEnvironments)
|
import Text.Pandoc.Readers.LaTeX.Table (tableEnvironments)
|
||||||
import Text.Pandoc.Readers.LaTeX.Lang (polyglossiaLangToBCP47,
|
import Text.Pandoc.Readers.LaTeX.Lang (polyglossiaLangToBCP47,
|
||||||
babelLangToBCP47)
|
babelLangToBCP47)
|
||||||
|
@ -169,7 +170,7 @@ rawLaTeXInline = do
|
||||||
let toks = tokenize "source" inp
|
let toks = tokenize "source" inp
|
||||||
raw <- snd <$>
|
raw <- snd <$>
|
||||||
( rawLaTeXParser toks True
|
( rawLaTeXParser toks True
|
||||||
(mempty <$ (controlSeq "input" >> skipMany opt >> braced))
|
(mempty <$ (controlSeq "input" >> skipMany rawopt >> braced))
|
||||||
inlines
|
inlines
|
||||||
<|> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
|
<|> rawLaTeXParser toks True (inlineEnvironment <|> inlineCommand')
|
||||||
inlines
|
inlines
|
||||||
|
@ -311,7 +312,7 @@ blockquote :: PandocMonad m => Bool -> Maybe Text -> LP m Blocks
|
||||||
blockquote cvariant mblang = do
|
blockquote cvariant mblang = do
|
||||||
citepar <- if cvariant
|
citepar <- if cvariant
|
||||||
then (\xs -> para (cite xs mempty))
|
then (\xs -> para (cite xs mempty))
|
||||||
<$> cites NormalCitation False
|
<$> cites inline NormalCitation False
|
||||||
else option mempty $ para <$> bracketed inline
|
else option mempty $ para <$> bracketed inline
|
||||||
let lang = mblang >>= babelLangToBCP47
|
let lang = mblang >>= babelLangToBCP47
|
||||||
let langdiv = case lang of
|
let langdiv = case lang of
|
||||||
|
@ -425,116 +426,6 @@ pDollarsMath n = do
|
||||||
else mzero
|
else mzero
|
||||||
_ -> (tk :) <$> pDollarsMath n
|
_ -> (tk :) <$> pDollarsMath n
|
||||||
|
|
||||||
-- citations
|
|
||||||
|
|
||||||
addPrefix :: [Inline] -> [Citation] -> [Citation]
|
|
||||||
addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
|
|
||||||
addPrefix _ _ = []
|
|
||||||
|
|
||||||
addSuffix :: [Inline] -> [Citation] -> [Citation]
|
|
||||||
addSuffix s ks@(_:_) =
|
|
||||||
let k = last ks
|
|
||||||
in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
|
|
||||||
addSuffix _ _ = []
|
|
||||||
|
|
||||||
simpleCiteArgs :: PandocMonad m => LP m [Citation]
|
|
||||||
simpleCiteArgs = try $ do
|
|
||||||
first <- optionMaybe $ toList <$> opt
|
|
||||||
second <- optionMaybe $ toList <$> opt
|
|
||||||
keys <- try $ bgroup *> manyTill citationLabel egroup
|
|
||||||
let (pre, suf) = case (first , second ) of
|
|
||||||
(Just s , Nothing) -> (mempty, s )
|
|
||||||
(Just s , Just t ) -> (s , t )
|
|
||||||
_ -> (mempty, mempty)
|
|
||||||
conv k = Citation { citationId = k
|
|
||||||
, citationPrefix = []
|
|
||||||
, citationSuffix = []
|
|
||||||
, citationMode = NormalCitation
|
|
||||||
, citationHash = 0
|
|
||||||
, citationNoteNum = 0
|
|
||||||
}
|
|
||||||
return $ addPrefix pre $ addSuffix suf $ map conv keys
|
|
||||||
|
|
||||||
citationLabel :: PandocMonad m => LP m Text
|
|
||||||
citationLabel = do
|
|
||||||
sp
|
|
||||||
untokenize <$>
|
|
||||||
(many1 (satisfyTok isWordTok <|> symbolIn bibtexKeyChar)
|
|
||||||
<* sp
|
|
||||||
<* optional (symbol ',')
|
|
||||||
<* sp)
|
|
||||||
where bibtexKeyChar = ".:;?!`'()/*@_+=-&[]" :: [Char]
|
|
||||||
|
|
||||||
cites :: PandocMonad m => CitationMode -> Bool -> LP m [Citation]
|
|
||||||
cites mode multi = try $ do
|
|
||||||
cits <- if multi
|
|
||||||
then do
|
|
||||||
multiprenote <- optionMaybe $ toList <$> paropt
|
|
||||||
multipostnote <- optionMaybe $ toList <$> paropt
|
|
||||||
let (pre, suf) = case (multiprenote, multipostnote) of
|
|
||||||
(Just s , Nothing) -> (mempty, s)
|
|
||||||
(Nothing , Just t) -> (mempty, t)
|
|
||||||
(Just s , Just t ) -> (s, t)
|
|
||||||
_ -> (mempty, mempty)
|
|
||||||
tempCits <- many1 simpleCiteArgs
|
|
||||||
case tempCits of
|
|
||||||
(k:ks) -> case ks of
|
|
||||||
(_:_) -> return $ (addMprenote pre k : init ks) ++
|
|
||||||
[addMpostnote suf (last ks)]
|
|
||||||
_ -> return [addMprenote pre (addMpostnote suf k)]
|
|
||||||
_ -> return [[]]
|
|
||||||
else count 1 simpleCiteArgs
|
|
||||||
let cs = concat cits
|
|
||||||
return $ case mode of
|
|
||||||
AuthorInText -> case cs of
|
|
||||||
(c:rest) -> c {citationMode = mode} : rest
|
|
||||||
[] -> []
|
|
||||||
_ -> map (\a -> a {citationMode = mode}) cs
|
|
||||||
where mprenote (k:ks) = (k:ks) ++ [Space]
|
|
||||||
mprenote _ = mempty
|
|
||||||
mpostnote (k:ks) = [Str ",", Space] ++ (k:ks)
|
|
||||||
mpostnote _ = mempty
|
|
||||||
addMprenote mpn (k:ks) =
|
|
||||||
let mpnfinal = case citationPrefix k of
|
|
||||||
(_:_) -> mprenote mpn
|
|
||||||
_ -> mpn
|
|
||||||
in addPrefix mpnfinal (k:ks)
|
|
||||||
addMprenote _ _ = []
|
|
||||||
addMpostnote = addSuffix . mpostnote
|
|
||||||
|
|
||||||
citation :: PandocMonad m => Text -> CitationMode -> Bool -> LP m Inlines
|
|
||||||
citation name mode multi = do
|
|
||||||
(c,raw) <- withRaw $ cites mode multi
|
|
||||||
return $ cite c (rawInline "latex" $ "\\" <> name <> untokenize raw)
|
|
||||||
|
|
||||||
handleCitationPart :: Inlines -> [Citation]
|
|
||||||
handleCitationPart ils =
|
|
||||||
let isCite Cite{} = True
|
|
||||||
isCite _ = False
|
|
||||||
(pref, rest) = break isCite (toList ils)
|
|
||||||
in case rest of
|
|
||||||
(Cite cs _:suff) -> addPrefix pref $ addSuffix suff cs
|
|
||||||
_ -> []
|
|
||||||
|
|
||||||
complexNatbibCitation :: PandocMonad m => CitationMode -> LP m Inlines
|
|
||||||
complexNatbibCitation mode = try $ do
|
|
||||||
(cs, raw) <-
|
|
||||||
withRaw $ concat <$> do
|
|
||||||
bgroup
|
|
||||||
items <- mconcat <$>
|
|
||||||
many1 (notFollowedBy (symbol ';') >> inline)
|
|
||||||
`sepBy1` symbol ';'
|
|
||||||
egroup
|
|
||||||
return $ map handleCitationPart items
|
|
||||||
case cs of
|
|
||||||
[] -> mzero
|
|
||||||
(c:cits) -> return $ cite (c{ citationMode = mode }:cits)
|
|
||||||
(rawInline "latex" $ "\\citetext" <> untokenize raw)
|
|
||||||
|
|
||||||
inNote :: Inlines -> Inlines
|
|
||||||
inNote ils =
|
|
||||||
note $ para $ ils <> str "."
|
|
||||||
|
|
||||||
inlineCommand' :: PandocMonad m => LP m Inlines
|
inlineCommand' :: PandocMonad m => LP m Inlines
|
||||||
inlineCommand' = try $ do
|
inlineCommand' = try $ do
|
||||||
Tok _ (CtrlSeq name) cmd <- anyControlSeq
|
Tok _ (CtrlSeq name) cmd <- anyControlSeq
|
||||||
|
@ -553,19 +444,6 @@ inlineCommand' = try $ do
|
||||||
tok :: PandocMonad m => LP m Inlines
|
tok :: PandocMonad m => LP m Inlines
|
||||||
tok = tokWith inline
|
tok = tokWith inline
|
||||||
|
|
||||||
opt :: PandocMonad m => LP m Inlines
|
|
||||||
opt = do
|
|
||||||
toks <- try (sp *> bracketedToks <* sp)
|
|
||||||
-- now parse the toks as inlines
|
|
||||||
st <- getState
|
|
||||||
parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
|
|
||||||
case parsed of
|
|
||||||
Right result -> return result
|
|
||||||
Left e -> throwError $ PandocParsecError (untokenize toks) e
|
|
||||||
|
|
||||||
paropt :: PandocMonad m => LP m Inlines
|
|
||||||
paropt = parenWrapped inline
|
|
||||||
|
|
||||||
inBrackets :: Inlines -> Inlines
|
inBrackets :: Inlines -> Inlines
|
||||||
inBrackets x = str "[" <> x <> str "]"
|
inBrackets x = str "[" <> x <> str "]"
|
||||||
|
|
||||||
|
@ -629,6 +507,7 @@ inlineCommands :: PandocMonad m => M.Map Text (LP m Inlines)
|
||||||
inlineCommands =
|
inlineCommands =
|
||||||
M.union inlineLanguageCommands $
|
M.union inlineLanguageCommands $
|
||||||
M.union (accentCommands tok) $
|
M.union (accentCommands tok) $
|
||||||
|
M.union (citationCommands inline) $
|
||||||
M.fromList
|
M.fromList
|
||||||
[ ("emph", extractSpaces emph <$> tok)
|
[ ("emph", extractSpaces emph <$> tok)
|
||||||
, ("textit", extractSpaces emph <$> tok)
|
, ("textit", extractSpaces emph <$> tok)
|
||||||
|
@ -703,7 +582,7 @@ inlineCommands =
|
||||||
, ("/", pure mempty) -- italic correction
|
, ("/", pure mempty) -- italic correction
|
||||||
, ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState
|
, ("\\", linebreak <$ (do inTableCell <- sInTableCell <$> getState
|
||||||
guard $ not inTableCell
|
guard $ not inTableCell
|
||||||
optional opt
|
optional rawopt
|
||||||
spaces))
|
spaces))
|
||||||
, (",", lit "\8198")
|
, (",", lit "\8198")
|
||||||
, ("@", pure mempty)
|
, ("@", pure mempty)
|
||||||
|
@ -761,61 +640,6 @@ inlineCommands =
|
||||||
, ("proofname", doTerm Translations.Proof)
|
, ("proofname", doTerm Translations.Proof)
|
||||||
, ("glossaryname", doTerm Translations.Glossary)
|
, ("glossaryname", doTerm Translations.Glossary)
|
||||||
, ("lstlistingname", doTerm Translations.Listing)
|
, ("lstlistingname", doTerm Translations.Listing)
|
||||||
, ("cite", citation "cite" NormalCitation False)
|
|
||||||
, ("Cite", citation "Cite" NormalCitation False)
|
|
||||||
, ("citep", citation "citep" NormalCitation False)
|
|
||||||
, ("citep*", citation "citep*" NormalCitation False)
|
|
||||||
, ("citeal", citation "citeal" NormalCitation False)
|
|
||||||
, ("citealp", citation "citealp" NormalCitation False)
|
|
||||||
, ("citealp*", citation "citealp*" NormalCitation False)
|
|
||||||
, ("autocite", citation "autocite" NormalCitation False)
|
|
||||||
, ("smartcite", citation "smartcite" NormalCitation False)
|
|
||||||
, ("footcite", inNote <$> citation "footcite" NormalCitation False)
|
|
||||||
, ("parencite", citation "parencite" NormalCitation False)
|
|
||||||
, ("supercite", citation "supercite" NormalCitation False)
|
|
||||||
, ("footcitetext", inNote <$> citation "footcitetext" NormalCitation False)
|
|
||||||
, ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
|
|
||||||
, ("citeyear", citation "citeyear" SuppressAuthor False)
|
|
||||||
, ("autocite*", citation "autocite*" SuppressAuthor False)
|
|
||||||
, ("cite*", citation "cite*" SuppressAuthor False)
|
|
||||||
, ("parencite*", citation "parencite*" SuppressAuthor False)
|
|
||||||
, ("textcite", citation "textcite" AuthorInText False)
|
|
||||||
, ("citet", citation "citet" AuthorInText False)
|
|
||||||
, ("citet*", citation "citet*" AuthorInText False)
|
|
||||||
, ("citealt", citation "citealt" AuthorInText False)
|
|
||||||
, ("citealt*", citation "citealt*" AuthorInText False)
|
|
||||||
, ("textcites", citation "textcites" AuthorInText True)
|
|
||||||
, ("cites", citation "cites" NormalCitation True)
|
|
||||||
, ("autocites", citation "autocites" NormalCitation True)
|
|
||||||
, ("footcites", inNote <$> citation "footcites" NormalCitation True)
|
|
||||||
, ("parencites", citation "parencites" NormalCitation True)
|
|
||||||
, ("supercites", citation "supercites" NormalCitation True)
|
|
||||||
, ("footcitetexts", inNote <$> citation "footcitetexts" NormalCitation True)
|
|
||||||
, ("Autocite", citation "Autocite" NormalCitation False)
|
|
||||||
, ("Smartcite", citation "Smartcite" NormalCitation False)
|
|
||||||
, ("Footcite", inNote <$> citation "Footcite" NormalCitation False)
|
|
||||||
, ("Parencite", citation "Parencite" NormalCitation False)
|
|
||||||
, ("Supercite", citation "Supercite" NormalCitation False)
|
|
||||||
, ("Footcitetext", inNote <$> citation "Footcitetext" NormalCitation False)
|
|
||||||
, ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
|
|
||||||
, ("Citeyear", citation "Citeyear" SuppressAuthor False)
|
|
||||||
, ("Autocite*", citation "Autocite*" SuppressAuthor False)
|
|
||||||
, ("Cite*", citation "Cite*" SuppressAuthor False)
|
|
||||||
, ("Parencite*", citation "Parencite*" SuppressAuthor False)
|
|
||||||
, ("Textcite", citation "Textcite" AuthorInText False)
|
|
||||||
, ("Textcites", citation "Textcites" AuthorInText True)
|
|
||||||
, ("Cites", citation "Cites" NormalCitation True)
|
|
||||||
, ("Autocites", citation "Autocites" NormalCitation True)
|
|
||||||
, ("Footcites", inNote <$> citation "Footcites" NormalCitation True)
|
|
||||||
, ("Parencites", citation "Parencites" NormalCitation True)
|
|
||||||
, ("Supercites", citation "Supercites" NormalCitation True)
|
|
||||||
, ("Footcitetexts", inNote <$> citation "Footcitetexts" NormalCitation True)
|
|
||||||
, ("citetext", complexNatbibCitation NormalCitation)
|
|
||||||
, ("citeauthor", (try (tok *> sp *> controlSeq "citetext") *>
|
|
||||||
complexNatbibCitation AuthorInText)
|
|
||||||
<|> citation "citeauthor" AuthorInText False)
|
|
||||||
, ("nocite", mempty <$ (citation "nocite" NormalCitation False >>=
|
|
||||||
addMeta "nocite"))
|
|
||||||
, ("hyperlink", hyperlink)
|
, ("hyperlink", hyperlink)
|
||||||
, ("hypertarget", hypertargetInline)
|
, ("hypertarget", hypertargetInline)
|
||||||
-- glossaries package
|
-- glossaries package
|
||||||
|
@ -918,7 +742,7 @@ inlineCommands =
|
||||||
|
|
||||||
lettrine :: PandocMonad m => LP m Inlines
|
lettrine :: PandocMonad m => LP m Inlines
|
||||||
lettrine = do
|
lettrine = do
|
||||||
optional opt
|
optional rawopt
|
||||||
x <- tok
|
x <- tok
|
||||||
y <- tok
|
y <- tok
|
||||||
return $ extractSpaces (spanWith ("",["lettrine"],[])) x <> smallcaps y
|
return $ extractSpaces (spanWith ("",["lettrine"],[])) x <> smallcaps y
|
||||||
|
@ -1168,6 +992,16 @@ inline = (mempty <$ comment)
|
||||||
inlines :: PandocMonad m => LP m Inlines
|
inlines :: PandocMonad m => LP m Inlines
|
||||||
inlines = mconcat <$> many inline
|
inlines = mconcat <$> many inline
|
||||||
|
|
||||||
|
opt :: PandocMonad m => LP m Inlines
|
||||||
|
opt = do
|
||||||
|
toks <- try (sp *> bracketedToks <* sp)
|
||||||
|
-- now parse the toks as inlines
|
||||||
|
st <- getState
|
||||||
|
parsed <- runParserT (mconcat <$> many inline) st "bracketed option" toks
|
||||||
|
case parsed of
|
||||||
|
Right result -> return result
|
||||||
|
Left e -> throwError $ PandocParsecError (untokenize toks) e
|
||||||
|
|
||||||
-- block elements:
|
-- block elements:
|
||||||
|
|
||||||
preamble :: PandocMonad m => LP m Blocks
|
preamble :: PandocMonad m => LP m Blocks
|
||||||
|
@ -1261,10 +1095,6 @@ insertIncluded defaultExtension f' = do
|
||||||
getInput >>= setInput . (tokenize f contents ++)
|
getInput >>= setInput . (tokenize f contents ++)
|
||||||
updateState dropLatestIncludeFile
|
updateState dropLatestIncludeFile
|
||||||
|
|
||||||
addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> LP m ()
|
|
||||||
addMeta field val = updateState $ \st ->
|
|
||||||
st{ sMeta = addMetaField field val $ sMeta st }
|
|
||||||
|
|
||||||
authors :: PandocMonad m => LP m ()
|
authors :: PandocMonad m => LP m ()
|
||||||
authors = try $ do
|
authors = try $ do
|
||||||
bgroup
|
bgroup
|
||||||
|
|
210
src/Text/Pandoc/Readers/LaTeX/Citation.hs
Normal file
210
src/Text/Pandoc/Readers/LaTeX/Citation.hs
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
module Text.Pandoc.Readers.LaTeX.Citation
|
||||||
|
( citationCommands
|
||||||
|
, cites
|
||||||
|
)
|
||||||
|
where
|
||||||
|
|
||||||
|
import Text.Pandoc.Class
|
||||||
|
import Text.Pandoc.Readers.LaTeX.Parsing
|
||||||
|
import Text.Pandoc.Builder as B
|
||||||
|
import qualified Data.Map as M
|
||||||
|
import Data.Text (Text)
|
||||||
|
import Control.Applicative ((<|>), optional, many)
|
||||||
|
import Control.Monad (mzero)
|
||||||
|
import Control.Monad.Trans (lift)
|
||||||
|
import Control.Monad.Except (throwError)
|
||||||
|
import Text.Pandoc.Error (PandocError(PandocParsecError))
|
||||||
|
import Text.Pandoc.Parsing hiding (blankline, many, mathDisplay, mathInline,
|
||||||
|
optional, space, spaces, withRaw, (<|>))
|
||||||
|
|
||||||
|
citationCommands :: PandocMonad m => LP m Inlines -> M.Map Text (LP m Inlines)
|
||||||
|
citationCommands inline =
|
||||||
|
let citation = citationWith inline
|
||||||
|
tok = spaces *> grouped inline
|
||||||
|
in M.fromList
|
||||||
|
[ ("cite", citation "cite" NormalCitation False)
|
||||||
|
, ("Cite", citation "Cite" NormalCitation False)
|
||||||
|
, ("citep", citation "citep" NormalCitation False)
|
||||||
|
, ("citep*", citation "citep*" NormalCitation False)
|
||||||
|
, ("citeal", citation "citeal" NormalCitation False)
|
||||||
|
, ("citealp", citation "citealp" NormalCitation False)
|
||||||
|
, ("citealp*", citation "citealp*" NormalCitation False)
|
||||||
|
, ("autocite", citation "autocite" NormalCitation False)
|
||||||
|
, ("smartcite", citation "smartcite" NormalCitation False)
|
||||||
|
, ("footcite", inNote <$> citation "footcite" NormalCitation False)
|
||||||
|
, ("parencite", citation "parencite" NormalCitation False)
|
||||||
|
, ("supercite", citation "supercite" NormalCitation False)
|
||||||
|
, ("footcitetext", inNote <$> citation "footcitetext" NormalCitation False)
|
||||||
|
, ("citeyearpar", citation "citeyearpar" SuppressAuthor False)
|
||||||
|
, ("citeyear", citation "citeyear" SuppressAuthor False)
|
||||||
|
, ("autocite*", citation "autocite*" SuppressAuthor False)
|
||||||
|
, ("cite*", citation "cite*" SuppressAuthor False)
|
||||||
|
, ("parencite*", citation "parencite*" SuppressAuthor False)
|
||||||
|
, ("textcite", citation "textcite" AuthorInText False)
|
||||||
|
, ("citet", citation "citet" AuthorInText False)
|
||||||
|
, ("citet*", citation "citet*" AuthorInText False)
|
||||||
|
, ("citealt", citation "citealt" AuthorInText False)
|
||||||
|
, ("citealt*", citation "citealt*" AuthorInText False)
|
||||||
|
, ("textcites", citation "textcites" AuthorInText True)
|
||||||
|
, ("cites", citation "cites" NormalCitation True)
|
||||||
|
, ("autocites", citation "autocites" NormalCitation True)
|
||||||
|
, ("footcites", inNote <$> citation "footcites" NormalCitation True)
|
||||||
|
, ("parencites", citation "parencites" NormalCitation True)
|
||||||
|
, ("supercites", citation "supercites" NormalCitation True)
|
||||||
|
, ("footcitetexts", inNote <$> citation "footcitetexts" NormalCitation True)
|
||||||
|
, ("Autocite", citation "Autocite" NormalCitation False)
|
||||||
|
, ("Smartcite", citation "Smartcite" NormalCitation False)
|
||||||
|
, ("Footcite", inNote <$> citation "Footcite" NormalCitation False)
|
||||||
|
, ("Parencite", citation "Parencite" NormalCitation False)
|
||||||
|
, ("Supercite", citation "Supercite" NormalCitation False)
|
||||||
|
, ("Footcitetext", inNote <$> citation "Footcitetext" NormalCitation False)
|
||||||
|
, ("Citeyearpar", citation "Citeyearpar" SuppressAuthor False)
|
||||||
|
, ("Citeyear", citation "Citeyear" SuppressAuthor False)
|
||||||
|
, ("Autocite*", citation "Autocite*" SuppressAuthor False)
|
||||||
|
, ("Cite*", citation "Cite*" SuppressAuthor False)
|
||||||
|
, ("Parencite*", citation "Parencite*" SuppressAuthor False)
|
||||||
|
, ("Textcite", citation "Textcite" AuthorInText False)
|
||||||
|
, ("Textcites", citation "Textcites" AuthorInText True)
|
||||||
|
, ("Cites", citation "Cites" NormalCitation True)
|
||||||
|
, ("Autocites", citation "Autocites" NormalCitation True)
|
||||||
|
, ("Footcites", inNote <$> citation "Footcites" NormalCitation True)
|
||||||
|
, ("Parencites", citation "Parencites" NormalCitation True)
|
||||||
|
, ("Supercites", citation "Supercites" NormalCitation True)
|
||||||
|
, ("Footcitetexts", inNote <$> citation "Footcitetexts" NormalCitation True)
|
||||||
|
, ("citetext", complexNatbibCitation inline NormalCitation)
|
||||||
|
, ("citeauthor", (try (tok *> sp *> controlSeq "citetext") *>
|
||||||
|
complexNatbibCitation inline AuthorInText)
|
||||||
|
<|> citation "citeauthor" AuthorInText False)
|
||||||
|
, ("nocite", mempty <$ (citation "nocite" NormalCitation False >>=
|
||||||
|
addMeta "nocite"))
|
||||||
|
]
|
||||||
|
|
||||||
|
-- citations
|
||||||
|
|
||||||
|
addPrefix :: [Inline] -> [Citation] -> [Citation]
|
||||||
|
addPrefix p (k:ks) = k {citationPrefix = p ++ citationPrefix k} : ks
|
||||||
|
addPrefix _ _ = []
|
||||||
|
|
||||||
|
addSuffix :: [Inline] -> [Citation] -> [Citation]
|
||||||
|
addSuffix s ks@(_:_) =
|
||||||
|
let k = last ks
|
||||||
|
in init ks ++ [k {citationSuffix = citationSuffix k ++ s}]
|
||||||
|
addSuffix _ _ = []
|
||||||
|
|
||||||
|
simpleCiteArgs :: forall m . PandocMonad m => LP m Inlines -> LP m [Citation]
|
||||||
|
simpleCiteArgs inline = try $ do
|
||||||
|
first <- optionMaybe $ toList <$> opt
|
||||||
|
second <- optionMaybe $ toList <$> opt
|
||||||
|
keys <- try $ bgroup *> manyTill citationLabel egroup
|
||||||
|
let (pre, suf) = case (first , second ) of
|
||||||
|
(Just s , Nothing) -> (mempty, s )
|
||||||
|
(Just s , Just t ) -> (s , t )
|
||||||
|
_ -> (mempty, mempty)
|
||||||
|
conv k = Citation { citationId = k
|
||||||
|
, citationPrefix = []
|
||||||
|
, citationSuffix = []
|
||||||
|
, citationMode = NormalCitation
|
||||||
|
, citationHash = 0
|
||||||
|
, citationNoteNum = 0
|
||||||
|
}
|
||||||
|
return $ addPrefix pre $ addSuffix suf $ map conv keys
|
||||||
|
where
|
||||||
|
opt :: PandocMonad m => LP m Inlines
|
||||||
|
opt = do
|
||||||
|
toks <- try (sp *> bracketedToks <* sp)
|
||||||
|
-- now parse the toks as inlines
|
||||||
|
st <- getState
|
||||||
|
parsed <- lift $
|
||||||
|
runParserT (mconcat <$> many inline) st "bracketed option" toks
|
||||||
|
case parsed of
|
||||||
|
Right result -> return result
|
||||||
|
Left e -> throwError $ PandocParsecError (untokenize toks) e
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
citationLabel :: PandocMonad m => LP m Text
|
||||||
|
citationLabel = do
|
||||||
|
sp
|
||||||
|
untokenize <$>
|
||||||
|
(many1 (satisfyTok isWordTok <|> symbolIn bibtexKeyChar)
|
||||||
|
<* sp
|
||||||
|
<* optional (symbol ',')
|
||||||
|
<* sp)
|
||||||
|
where bibtexKeyChar = ".:;?!`'()/*@_+=-&[]" :: [Char]
|
||||||
|
|
||||||
|
cites :: PandocMonad m
|
||||||
|
=> LP m Inlines -> CitationMode -> Bool -> LP m [Citation]
|
||||||
|
cites inline mode multi = try $ do
|
||||||
|
let paropt = parenWrapped inline
|
||||||
|
cits <- if multi
|
||||||
|
then do
|
||||||
|
multiprenote <- optionMaybe $ toList <$> paropt
|
||||||
|
multipostnote <- optionMaybe $ toList <$> paropt
|
||||||
|
let (pre, suf) = case (multiprenote, multipostnote) of
|
||||||
|
(Just s , Nothing) -> (mempty, s)
|
||||||
|
(Nothing , Just t) -> (mempty, t)
|
||||||
|
(Just s , Just t ) -> (s, t)
|
||||||
|
_ -> (mempty, mempty)
|
||||||
|
tempCits <- many1 $ simpleCiteArgs inline
|
||||||
|
case tempCits of
|
||||||
|
(k:ks) -> case ks of
|
||||||
|
(_:_) -> return $ (addMprenote pre k : init ks) ++
|
||||||
|
[addMpostnote suf (last ks)]
|
||||||
|
_ -> return [addMprenote pre (addMpostnote suf k)]
|
||||||
|
_ -> return [[]]
|
||||||
|
else count 1 $ simpleCiteArgs inline
|
||||||
|
let cs = concat cits
|
||||||
|
return $ case mode of
|
||||||
|
AuthorInText -> case cs of
|
||||||
|
(c:rest) -> c {citationMode = mode} : rest
|
||||||
|
[] -> []
|
||||||
|
_ -> map (\a -> a {citationMode = mode}) cs
|
||||||
|
where mprenote (k:ks) = (k:ks) ++ [Space]
|
||||||
|
mprenote _ = mempty
|
||||||
|
mpostnote (k:ks) = [Str ",", Space] ++ (k:ks)
|
||||||
|
mpostnote _ = mempty
|
||||||
|
addMprenote mpn (k:ks) =
|
||||||
|
let mpnfinal = case citationPrefix k of
|
||||||
|
(_:_) -> mprenote mpn
|
||||||
|
_ -> mpn
|
||||||
|
in addPrefix mpnfinal (k:ks)
|
||||||
|
addMprenote _ _ = []
|
||||||
|
addMpostnote = addSuffix . mpostnote
|
||||||
|
|
||||||
|
citationWith :: PandocMonad m
|
||||||
|
=> LP m Inlines -> Text -> CitationMode -> Bool -> LP m Inlines
|
||||||
|
citationWith inline name mode multi = do
|
||||||
|
(c,raw) <- withRaw $ cites inline mode multi
|
||||||
|
return $ cite c (rawInline "latex" $ "\\" <> name <> untokenize raw)
|
||||||
|
|
||||||
|
handleCitationPart :: Inlines -> [Citation]
|
||||||
|
handleCitationPart ils =
|
||||||
|
let isCite Cite{} = True
|
||||||
|
isCite _ = False
|
||||||
|
(pref, rest) = break isCite (toList ils)
|
||||||
|
in case rest of
|
||||||
|
(Cite cs _:suff) -> addPrefix pref $ addSuffix suff cs
|
||||||
|
_ -> []
|
||||||
|
|
||||||
|
complexNatbibCitation :: PandocMonad m
|
||||||
|
=> LP m Inlines -> CitationMode -> LP m Inlines
|
||||||
|
complexNatbibCitation inline mode = try $ do
|
||||||
|
(cs, raw) <-
|
||||||
|
withRaw $ concat <$> do
|
||||||
|
bgroup
|
||||||
|
items <- mconcat <$>
|
||||||
|
many1 (notFollowedBy (symbol ';') >> inline)
|
||||||
|
`sepBy1` symbol ';'
|
||||||
|
egroup
|
||||||
|
return $ map handleCitationPart items
|
||||||
|
case cs of
|
||||||
|
[] -> mzero
|
||||||
|
(c:cits) -> return $ cite (c{ citationMode = mode }:cits)
|
||||||
|
(rawInline "latex" $ "\\citetext" <> untokenize raw)
|
||||||
|
|
||||||
|
inNote :: Inlines -> Inlines
|
||||||
|
inNote ils =
|
||||||
|
note $ para $ ils <> str "."
|
||||||
|
|
|
@ -85,6 +85,7 @@ module Text.Pandoc.Readers.LaTeX.Parsing
|
||||||
, setCaption
|
, setCaption
|
||||||
, resetCaption
|
, resetCaption
|
||||||
, env
|
, env
|
||||||
|
, addMeta
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Applicative (many, (<|>))
|
import Control.Applicative (many, (<|>))
|
||||||
|
@ -947,3 +948,7 @@ tokWith inlineParser = try $ spaces >>
|
||||||
where singleChar' = do
|
where singleChar' = do
|
||||||
Tok _ _ t <- singleChar
|
Tok _ _ t <- singleChar
|
||||||
return $ str t
|
return $ str t
|
||||||
|
|
||||||
|
addMeta :: PandocMonad m => ToMetaValue a => Text -> a -> LP m ()
|
||||||
|
addMeta field val = updateState $ \st ->
|
||||||
|
st{ sMeta = addMetaField field val $ sMeta st }
|
||||||
|
|
Loading…
Add table
Reference in a new issue