使用 bookdown/latex 创建 PDF 时 Backrefs 不起作用

使用 bookdown/latex 创建 PDF 时 Backrefs 不起作用

我正在用 latex/PDF 写一本书R/预订。我试图在参考书目中包含每篇文章被引用的页面列表(即反向引用)。但是, latex 包的backref和选项对于 PDF 输出不起作用。pagebackrefhyperref

这是我在序言中尝试包含反向引用的代码:

\usepackage[pagebackref=true]{hyperref}

但是,这不会在我的参考书目中的文章旁边创建“引用的页面”列表。我正在使用apa.csl引用样式语言和krantz2文档类别(krantz.cls)。

.tex以下是生成的文件的内容:

% Options for packages loaded elsewhere
\PassOptionsToPackage{unicode}{hyperref}
\PassOptionsToPackage{hyphens}{url}
%
\documentclass[
  krantz2]{krantz}
\usepackage{amsmath,amssymb}
\usepackage{lmodern}
\usepackage{iftex}
\ifPDFTeX
  \usepackage[T1]{fontenc}
  \usepackage[utf8]{inputenc}
  \usepackage{textcomp} % provide euro and other symbols
\else % if luatex or xetex
  \usepackage{unicode-math}
  \defaultfontfeatures{Scale=MatchLowercase}
  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
\fi
% Use upquote if available, for straight quotes in verbatim environments
\IfFileExists{upquote.sty}{\usepackage{upquote}}{}
\IfFileExists{microtype.sty}{% use microtype if available
  \usepackage[]{microtype}
  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
}{}
\makeatletter
\@ifundefined{KOMAClassName}{% if non-KOMA class
  \IfFileExists{parskip.sty}{%
    \usepackage{parskip}
  }{% else
    \setlength{\parindent}{0pt}
    \setlength{\parskip}{6pt plus 2pt minus 1pt}}
}{% if KOMA class
  \KOMAoptions{parskip=half}}
\makeatother
\usepackage{xcolor}
\usepackage{longtable,booktabs,array}
\usepackage{calc} % for calculating minipage widths
% Correct order of tables after \paragraph or \subparagraph
\usepackage{etoolbox}
\makeatletter
\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
\makeatother
% Allow footnotes in longtable head/foot
\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
\makesavenoteenv{longtable}
\setlength{\emergencystretch}{3em} % prevent overfull lines
\providecommand{\tightlist}{%
  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\setcounter{secnumdepth}{5}
\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}
 }%
 {}
\usepackage{calc}
\newcommand{\CSLBlock}[1]{#1\hfill\break}
\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}}
\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break}
\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage[bf,singlelinecheck=off]{caption}
\captionsetup[table]{labelsep=space}
\captionsetup[figure]{labelsep=space}
\usepackage[scale=.8]{sourcecodepro}

\usepackage{framed,color}
\definecolor{shadecolor}{RGB}{248,248,248}

\renewcommand{\textfraction}{0.05}
\renewcommand{\topfraction}{0.8}
\renewcommand{\bottomfraction}{0.8}
\renewcommand{\floatpagefraction}{0.75}

\renewenvironment{quote}{\begin{VF}}{\end{VF}}
\usepackage[pagebackref=true]{hyperref}
\let\oldhref\href
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}

\makeatletter
\newenvironment{kframe}{%
\medskip{}
\setlength{\fboxsep}{.8em}
 \def\at@end@of@kframe{}%
 \ifinner\ifhmode%
  \def\at@end@of@kframe{\end{minipage}}%
  \begin{minipage}{\columnwidth}%
 \fi\fi%
 \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
 \colorbox{shadecolor}{##1}\hskip-\fboxsep
     % There is no \\@totalrightmargin, so:
     \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
 \MakeFramed {\advance\hsize-\width
   \@totalleftmargin\z@ \linewidth\hsize
   \@setminipage}}%
 {\par\unskip\endMakeFramed%
 \at@end@of@kframe}
\makeatother

\makeatletter
\@ifundefined{Shaded}{
}{\renewenvironment{Shaded}{\begin{kframe}}{\end{kframe}}}
\makeatother

\usepackage{makeidx}
\makeindex

% to create a "see also" that appears at the bottom of the
% subentries and with no page number, do the following:
% \index{Main entry!zzzzz@\igobble|seealso{Other item}}

\newcommand{\ii}[1]{{\it #1}}
\newcommand{\nn}[1]{#1n}

\def\igobble#1{}

\urlstyle{tt}

\usepackage{amsthm}
\makeatletter
\def\thm@space@setup{%
  \thm@preskip=8pt plus 2pt minus 4pt
  \thm@postskip=\thm@preskip
}
\makeatother

\frontmatter
\ifLuaTeX
  \usepackage{selnolig}  % disable illegal ligatures
\fi
\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
\urlstyle{same} % disable monospaced font for URLs
\hypersetup{
  pdftitle={Book Title},
  pdfauthor={Author Name},
  hidelinks,
  pdfcreator={LaTeX via pandoc}}

\title{Book Title}
\author{Author Name}
\date{2023-08-16}

\begin{document}
\maketitle

\thispagestyle{empty}

\begin{center}
INSERT DEDICATION
\end{center}

\setlength{\abovedisplayskip}{-5pt}
\setlength{\abovedisplayshortskip}{-5pt}

{
\setcounter{tocdepth}{1}
\tableofcontents
}
\hypertarget{preface}{%
\chapter*{Preface}\label{preface}}


INSERT TEXT HERE (Xie, 2022).

\hypertarget{references}{%
\chapter*{References}\label{references}}


\hypertarget{refs}{}
\begin{CSLReferences}{1}{0}
\leavevmode\vadjust pre{\hypertarget{ref-R-bookdown}{}}%
Xie, Y. (2022). \emph{{bookdown}: Authoring books and technical documents with {R} {Markdown}}. \url{https://CRAN.R-project.org/package=bookdown}

\end{CSLReferences}

\backmatter
\printindex

\end{document}

以下是可重现的最小示例(以及apa.cslkrantz.cls—我不确定如何使这两个文件“最小化”)生成上述.tex文件:

index.rmd

---
title: "Book Title"
author: "Author Name"
date: "`r Sys.Date()`"
documentclass: krantz
classoption: krantz2
bibliography: [book.bib]
site: bookdown::bookdown_site
---

01-Preface.rmd

# Preface {-}

INSERT TEXT HERE [@R-bookdown].

preamble.tex

\usepackage{booktabs}
\usepackage{longtable}
\usepackage[bf,singlelinecheck=off]{caption}
\captionsetup[table]{labelsep=space}
\captionsetup[figure]{labelsep=space}
\usepackage[scale=.8]{sourcecodepro}

\usepackage{framed,color}
\definecolor{shadecolor}{RGB}{248,248,248}

\renewcommand{\textfraction}{0.05}
\renewcommand{\topfraction}{0.8}
\renewcommand{\bottomfraction}{0.8}
\renewcommand{\floatpagefraction}{0.75}

\renewenvironment{quote}{\begin{VF}}{\end{VF}}
\usepackage[pagebackref=true]{hyperref}
\let\oldhref\href
\renewcommand{\href}[2]{#2\footnote{\url{#1}}}

\makeatletter
\newenvironment{kframe}{%
\medskip{}
\setlength{\fboxsep}{.8em}
 \def\at@end@of@kframe{}%
 \ifinner\ifhmode%
  \def\at@end@of@kframe{\end{minipage}}%
  \begin{minipage}{\columnwidth}%
 \fi\fi%
 \def\FrameCommand##1{\hskip\@totalleftmargin \hskip-\fboxsep
 \colorbox{shadecolor}{##1}\hskip-\fboxsep
     % There is no \\@totalrightmargin, so:
     \hskip-\linewidth \hskip-\@totalleftmargin \hskip\columnwidth}%
 \MakeFramed {\advance\hsize-\width
   \@totalleftmargin\z@ \linewidth\hsize
   \@setminipage}}%
 {\par\unskip\endMakeFramed%
 \at@end@of@kframe}
\makeatother

\makeatletter
\@ifundefined{Shaded}{
}{\renewenvironment{Shaded}{\begin{kframe}}{\end{kframe}}}
\makeatother

\usepackage{makeidx}
\makeindex

\newcommand{\ii}[1]{{\it #1}}
\newcommand{\nn}[1]{#1n}

\def\igobble#1{}

\urlstyle{tt}

\usepackage{amsthm}
\makeatletter
\def\thm@space@setup{%
  \thm@preskip=8pt plus 2pt minus 4pt
  \thm@postskip=\thm@preskip
}
\makeatother

\frontmatter

after_body.tex

\backmatter
\printindex

book.bib

@Manual{R-bookdown,
  title  = {{bookdown}: Authoring books and technical documents with {R} {Markdown}},
  author = {Yihui Xie},
  note   = {R package version 0.26},
  year   = {2022},
  url    = {https://CRAN.R-project.org/package=bookdown},
}

_output.yml

bookdown::pdf_book:
  includes:
    in_header: latex/preamble.tex
    after_body: latex/after_body.tex
  keep_tex: true
  dev: "cairo_pdf"
  latex_engine: xelatex
  citation_package: none
  template: null
  pandoc_args: [ "--csl", "apa.csl", "--top-level-division=chapter" ]
  toc_depth: 2
  toc_unnumbered: false
  toc_appendix: true
  quote_footer: ["\\VA{", "}{}"]
  highlight_bw: true

如果您想查看完整、可重复的示例,请参见此处: https://github.com/isaactpetersen/mre

您可以在 repo 的 GitHub Actions 工作流中看到最小可重现示例的输出 pdf(单击最近的工作流运行,然后单击_book下载包含 PDF 的工件): https://github.com/isaactpetersen/mre/actions

答案1

这就是我的答案。但是,正如评论中多次提到的那样,您的代码和工作流程太长了,无法自己运行所有命令并调试输出。

由于您使用cslpandoc 样式,因此不会bibitems生成任何hyperref可以用作参考点的内容。我建议运行 pandoc 而不citeproc使用biblatex选项来输出tex文件。类似于pandoc <your input file> -t latex --biblatex -o xyz.tex使用合适的文件和附加参数。

然后,您可以设置正确的biblatex选项,如等style=apa,并使用和backref编译文件。texxelatexbiber

注意力:如上所述,由于您的文件内容丰富且工作流程复杂,我没有测试 R-markdown 兼容性和输出。

答案2

根据这个关联,应该可以配置 latex 书目处理的使用,我希望这反过来可以导致 hyperref 对此采取行动。他们说的是:

By default, citations are processed through pandoc-citeproc,
which works for all output formats. For PDF output, sometimes
it is better to use LaTeX packages to process citations, such
as natbib or biblatex. To use one of these packages, just set
the option citation_package to be natbib or biblatex, e.g.
---
output:
  pdf_document:
    citation_package: natbib
---

在我看来,当然,你必须使用 PDF 输出。hyperref例如,我不认为它能够修改 HTML 输出流。即使我错了,你至少应该最初不要这样做output_format = c("all"))切换到 PDF 输出(请参阅关联),并使用 citation_package与上面类似的方法。

如果这不能很快产生结果,我建议首先从一些新的小项目开始,并按照手册的建议进行练习,然后再返回到您的大项目。例如这里我发现你的代码bookdown::pdf_book很可能已经是R代码了,而不仅仅是标记。虽然它似乎不排除 latex 文献处理,但对于大多数 TeX 使用者来说,它可能太复杂/陌生了,对我来说肯定是这样的。

相同关联还提到了一些可能有用的、更复杂的例子,这些例子确实有效(或者由于错误而无效)。

相关内容