mirror of
https://github.com/jgm/pandoc.git
synced 2026-08-29 01:41:20 +08:00
Use \cite and \bibitem to link up citations, even with citeproc.
See #9031 and discussion in #9020. This will give us better accessibility; when tagging is enabled, the citation can be linked to the bibliography entry. This changes some of the details of the layout and the default template. We now make CSLReferences a special enumitem list that will contain `\bibitem`s. Internal links inside citations to ids beginning in `ref-` are put inside a `\cite` instead of `\hyperref`. Closes #9031.
This commit is contained in:
@@ -335,24 +335,28 @@ $if(pagestyle)$
|
||||
\pagestyle{$pagestyle$}
|
||||
$endif$
|
||||
$if(csl-refs)$
|
||||
% definitions for citeproc citations
|
||||
\NewDocumentCommand\citeproctext{}{}
|
||||
\NewDocumentCommand\citeproc{mm}{%
|
||||
\begingroup\def\citeproctext{#2}\cite{#1}\endgroup}
|
||||
% avoid brackets around text for \cite:
|
||||
\makeatletter
|
||||
\def\@biblabel#1{}
|
||||
\def\@cite#1#2{{#1\if@tempswa , #2\fi}}
|
||||
\makeatother
|
||||
\newlength{\cslhangindent}
|
||||
\setlength{\cslhangindent}{1.5em}
|
||||
\newlength{\csllabelwidth}
|
||||
\setlength{\csllabelwidth}{3em}
|
||||
\newlength{\cslentryspacingunit} % times entry-spacing
|
||||
\setlength{\cslentryspacingunit}{\parskip}
|
||||
\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing
|
||||
{% don't indent paragraphs
|
||||
\setlength{\parindent}{0pt}
|
||||
% turn on hanging indent if param 1 is 1
|
||||
\ifodd #1
|
||||
\let\oldpar\par
|
||||
\def\par{\hangindent=\cslhangindent\oldpar}
|
||||
\fi
|
||||
% set entry spacing
|
||||
\setlength{\parskip}{#2\cslentryspacingunit}
|
||||
}%
|
||||
{}
|
||||
\newlength{\cslentryspacing}
|
||||
\setlength{\cslentryspacing}{0em}
|
||||
\usepackage{enumitem}
|
||||
\newlist{CSLReferences}{itemize}{1}
|
||||
\setlist[CSLReferences]{label={},
|
||||
leftmargin=\cslhangindent,
|
||||
itemindent=-1\cslhangindent,
|
||||
parsep=\parskip,
|
||||
itemsep=\cslentryspacing}
|
||||
\usepackage{calc}
|
||||
\newcommand{\CSLBlock}[1]{#1\hfill\break}
|
||||
\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}}
|
||||
|
||||
@@ -339,22 +339,30 @@ blockToLaTeX (Div (identifier,classes,kvs) bs) = do
|
||||
then do
|
||||
modify $ \st -> st{ stHasCslRefs = True }
|
||||
inner <- blockListToLaTeX bs
|
||||
return $ "\\begin{CSLReferences}" <>
|
||||
(if "hanging-indent" `elem` classes
|
||||
then braces "1"
|
||||
else braces "0") <>
|
||||
(case lookup "entry-spacing" kvs of
|
||||
Nothing -> braces "0"
|
||||
Just s -> braces (literal s))
|
||||
return $ (if "hanging-indent" `notElem` classes
|
||||
then "\\setlength{\\cslhangindent}{0em}"
|
||||
else mempty)
|
||||
$$ ("\\setlength{\\cslentryspacing}" <> braces
|
||||
(case lookup "entry-spacing" kvs of
|
||||
Nothing -> "0em"
|
||||
Just s -> (literal s <> "\\baselineskip")))
|
||||
$$ "\\begin{CSLReferences}"
|
||||
$$ inner
|
||||
$+$ "\\end{CSLReferences}"
|
||||
else blockListToLaTeX bs
|
||||
modify $ \st -> st{ stIncremental = oldIncremental }
|
||||
linkAnchor <- hypertarget identifier
|
||||
let wrapNotes txt = if beamer && "notes" `elem` classes
|
||||
then "\\note" <> braces txt -- speaker notes
|
||||
else linkAnchor $$ txt
|
||||
wrapNotes <$> wrapDiv (identifier,classes,kvs) result
|
||||
let wrap txt
|
||||
| beamer && "notes" `elem` classes
|
||||
= pure ("\\note" <> braces txt) -- speaker notes
|
||||
| "ref-" `T.isPrefixOf` identifier
|
||||
= do
|
||||
lab <- toLabel identifier
|
||||
pure $ ("\\bibitem" <> brackets "\\citeproctext"
|
||||
<> braces (literal lab)) $$ txt
|
||||
| otherwise = do
|
||||
linkAnchor <- hypertarget identifier
|
||||
pure $ linkAnchor $$ txt
|
||||
wrapDiv (identifier,classes,kvs) result >>= wrap
|
||||
blockToLaTeX (Plain lst) =
|
||||
inlineListToLaTeX lst
|
||||
-- . . . indicates pause in beamer slides
|
||||
@@ -816,12 +824,14 @@ inlineToLaTeX (Subscript lst) =
|
||||
inlineToLaTeX (SmallCaps lst) =
|
||||
inCmd "textsc"<$> inlineListToLaTeX lst
|
||||
inlineToLaTeX (Cite cits lst) = do
|
||||
st <- get
|
||||
let opts = stOptions st
|
||||
case writerCiteMethod opts of
|
||||
Natbib -> citationsToNatbib inlineListToLaTeX cits
|
||||
Biblatex -> citationsToBiblatex inlineListToLaTeX cits
|
||||
_ -> inlineListToLaTeX lst
|
||||
opts <- gets stOptions
|
||||
modify $ \st -> st{ stInCite = True }
|
||||
res <- case writerCiteMethod opts of
|
||||
Natbib -> citationsToNatbib inlineListToLaTeX cits
|
||||
Biblatex -> citationsToBiblatex inlineListToLaTeX cits
|
||||
_ -> inlineListToLaTeX lst
|
||||
modify $ \st -> st{ stInCite = False }
|
||||
pure res
|
||||
|
||||
inlineToLaTeX (Code (_,classes,kvs) str) = do
|
||||
opts <- gets stOptions
|
||||
@@ -945,11 +955,14 @@ inlineToLaTeX (Link (id',_,_) txt (src,_)) =
|
||||
Just ('#', ident) -> do
|
||||
contents <- inlineListToLaTeX txt
|
||||
lab <- toLabel ident
|
||||
inCite <- gets stInCite
|
||||
beamer <- gets stBeamer
|
||||
return $
|
||||
if beamer
|
||||
then text "\\hyperlink" <> braces (literal lab) <> braces contents
|
||||
else text "\\hyperref" <> brackets (literal lab) <> braces contents
|
||||
if inCite && "#ref-" `T.isPrefixOf` src
|
||||
then "\\citeproc" <> braces (literal lab) <> braces contents
|
||||
else if beamer
|
||||
then "\\hyperlink" <> braces (literal lab) <> braces contents
|
||||
else "\\hyperref" <> brackets (literal lab) <> braces contents
|
||||
_ -> case txt of
|
||||
[Str x] | unEscapeString (T.unpack x) == unEscapeString (T.unpack src) -> -- autolink
|
||||
do modify $ \s -> s{ stUrl = True }
|
||||
|
||||
@@ -26,6 +26,7 @@ data WriterState =
|
||||
, stInHeading :: Bool -- ^ true if in a section heading
|
||||
, stInItem :: Bool -- ^ true if in \item[..]
|
||||
, stInFigure :: Bool -- ^ true if in figure environment
|
||||
, stInCite :: Bool -- ^ true if in a Cite
|
||||
, stNotes :: [Doc Text] -- ^ notes in a minipage
|
||||
, stOLLevel :: Int -- ^ level of ordered list nesting
|
||||
, stOptions :: WriterOptions -- ^ writer options, so they don't have to
|
||||
@@ -61,6 +62,7 @@ startingState options =
|
||||
, stInMinipage = False
|
||||
, stInItem = False
|
||||
, stInFigure = False
|
||||
, stInCite = False
|
||||
, stNotes = []
|
||||
, stOLLevel = 1
|
||||
, stOptions = options
|
||||
|
||||
Reference in New Issue
Block a user