回答这个问题奥黛丽提出一个答案与该authoryear
选项配合得很好。
(上下文:我试图让引文中的超链接包含作者姓名,而不仅仅是年份。奥黛丽提供了一个适用于 的解决方案authoryear
,我正在尝试使其适应authoryear-comp
。)
我正在尝试调整答案以使其与 兼容authoryear-comp
。以下是我尝试的方法(它不起作用---我收到一条错误消息:Latex Error: ./biblatex.tex:96 Argument of \@secondoftwo has an extra }. Runaway argument?
):
\renewbibmacro*{cite}{%
\printtext[bibhyperref]{% Enclose cite macro output in hyperlink
\global\togglefalse{cbx:hyperref}% Prevent nested hyperlinks
\iffieldundef{shorthand}
{\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
{\usebibmacro{cite:label}%
\setunit{\addspace}%
\usebibmacro{cite:labelyear+extrayear}%
\usebibmacro{cite:reinit}}
{\iffieldequals{namehash}{\cbx@lasthash}
{\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
\(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
{\setunit{\addcomma}%
\usebibmacro{cite:extrayear}}
{\setunit{\compcitedelim}%
\usebibmacro{cite:labelyear+extrayear}%
\savefield{labelyear}{\cbx@lastyear}}}
{\printnames{labelname}%
\setunit{\nameyeardelim}%
\usebibmacro{cite:labelyear+extrayear}%
\savefield{namehash}{\cbx@lasthash}%
\savefield{labelyear}{\cbx@lastyear}}}}
{\usebibmacro{cite:shorthand}%
\usebibmacro{cite:reinit}}%
\global\toggletrue{cbx:hyperref}}
\setunit{\multicitedelim}}
我不完全了解\cite
在 下是如何工作的authoryear-comp
,所以也许有人知道可以做到这一点?(我认为这是可能的,因为这是在 BibTeX 中实现超链接的方式。)
编辑(关于 Marco 的评论):这是一个最简单的例子:
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[style=authoryear-comp]{biblatex}
\usepackage[colorlinks]{hyperref}
\bibliography{biblatex-examples}
\newtoggle{cbx:hyperref}
\toggletrue{cbx:hyperref}
\DeclareFieldFormat{bibhyperref}{% Adapted from bibhyperref format in biblatex.def
\iftoggle{cbx:hyperref}
{\bibhyperref{#1}}
{#1}}
\renewbibmacro*{cite}{%
\printtext[bibhyperref]{% Enclose cite macro output in hyperlink
\global\togglefalse{cbx:hyperref}% Prevent nested hyperlinks
\iffieldundef{shorthand}
{\ifthenelse{\ifnameundef{labelname}\OR\iffieldundef{labelyear}}
{\usebibmacro{cite:label}%
\setunit{\addspace}%
\usebibmacro{cite:labelyear+extrayear}%
\usebibmacro{cite:reinit}}
{\iffieldequals{namehash}{\cbx@lasthash}
{\ifthenelse{\iffieldequals{labelyear}{\cbx@lastyear}\AND
\(\value{multicitecount}=0\OR\iffieldundef{postnote}\)}
{\setunit{\addcomma}%
\usebibmacro{cite:extrayear}}
{\setunit{\compcitedelim}%
\usebibmacro{cite:labelyear+extrayear}%
\savefield{labelyear}{\cbx@lastyear}}}
{\printnames{labelname}%
\setunit{\nameyeardelim}%
\usebibmacro{cite:labelyear+extrayear}%
\savefield{namehash}{\cbx@lasthash}%
\savefield{labelyear}{\cbx@lastyear}}}}
{\usebibmacro{cite:shorthand}%
\usebibmacro{cite:reinit}}%
\global\toggletrue{cbx:hyperref}}
\setunit{\multicitedelim}}
\DeclareCiteCommand{\textcite}% Adapted from \textcite command in authoryear.cbx
{\boolfalse{cbx:parens}}
{\usebibmacro{citeindex}%
\printtext[bibhyperref]{% Enclose textcite macro output in hyperlink
\global\togglefalse{cbx:hyperref}% Prevent nested hyperlinks
\usebibmacro{textcite}%
\iffieldundef{postnote}% Include closing parenthesis if no postnote
{\ifbool{cbx:parens}
{\bibcloseparen\global\boolfalse{cbx:parens}}
{}}
{}}%
\global\toggletrue{cbx:hyperref}}
{\ifbool{cbx:parens}
{\bibcloseparen\global\boolfalse{cbx:parens}}
{}%
\multicitedelim}
{\iffieldundef{postnote}
{}
{\usebibmacro{textcite:postnote}}}
\begin{document}
A reference to \parencite{kastenholz,sigfridsson} and~\cite{sigfridsson}.
\printbibliography
\end{document}
我正在使用biblatex-example
数据库中的引用。我得到的错误是:Paragraph ended before \@secondoftwo was complete.
答案1
我更喜欢另一种解决方案:
\makeatletter
%Works without the last bracket ;-)
\let\abx@macro@citeOrig\abx@macro@cite
\renewbibmacro{cite}{%
\bibhyperref{%
\let\bibhyperref\relax\relax%
\abx@macro@citeOrig%
}%
}
\let\abx@macro@textciteOrig\abx@macro@textcite
\renewbibmacro{textcite}{%
\bibhyperref{%
\let\bibhyperref\relax\relax%
\abx@macro@textciteOrig%
}%
}%
\makeatother
您可以将它用于每个 cite 命令。
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[style=authoryear-comp,backend=biber,hyperref]{biblatex}
\usepackage[colorlinks]{hyperref}
\bibliography{biblatex-examples}
\makeatletter
%Works without the last bracket ;-)
\let\abx@macro@citeOrig\abx@macro@cite
\renewbibmacro{cite}{%
\bibhyperref{%
\let\bibhyperref\relax\relax%
\abx@macro@citeOrig%
}%
}
\let\abx@macro@textciteOrig\abx@macro@textcite
\renewbibmacro{textcite}{%
\bibhyperref{%
\let\bibhyperref\relax\relax%
\abx@macro@textciteOrig%
}%
}%
\makeatother
\begin{document}
A reference to \parencite{kastenholz,sigfridsson} and~\cite{sigfridsson}.
\printbibliography
\end{document}
编辑:
我改变了上面例子的代码。
\makeatletter
\patchcmd{\blx@citeprint}%
{\blx@loopcode}%
{\blx@imc@bibhyperlink{#1}{\blx@loopcode}}%
{}{}
\makeatother
问题:最后一个括号不是链接的一部分。
答案2
\cite
和都在的参数内\textcite
使用。如果您只是在 中包装(或和书目宏),链接将包含标点符号。此外, 的打印被推迟到下一个或命令。因此很难确保这种方法会创建指向书目中正确项目的链接。\setunit
<loopcode>
\DeclareCiteCommand
<loopcode>
cite
textcite
\bibhyperref
\setunit
\print*
\bibstring
以下补丁将在适当的情况下为/和+cite
生成单个链接。补丁将在缺少和时在+周围添加括号。否则将应用单独的链接,类似于使用 natbib 获得的引用链接。labelname
label
labelyear
extrayear
textcite
labelyear
extrayear
prenote
postnote
\documentclass{report}
\usepackage[style=authoryear-comp]{biblatex}
\usepackage{hyperref}
\usepackage{xpatch}
% Just for demo
\ExecuteBibliographyOptions{maxcitenames=1}
% Combine label and labelyear links
\xpatchbibmacro{cite}
{\usebibmacro{cite:label}%
\setunit{\printdelim{nonameyeardelim}}%
\usebibmacro{cite:labeldate+extradate}}
{\printtext[bibhyperref]{%
\DeclareFieldAlias{bibhyperref}{default}%
\usebibmacro{cite:label}%
\setunit{\printdelim{nonameyeardelim}}%
\usebibmacro{cite:labeldate+extradate}}}
{}
{\PackageWarning{biblatex-patch}
{Failed to patch cite bibmacro}}
% Include labelname in labelyear link
\xpatchbibmacro{cite}
{\printnames{labelname}%
\setunit{\printdelim{nameyeardelim}}%
\usebibmacro{cite:labeldate+extradate}}
{\printtext[bibhyperref]{%
\DeclareFieldAlias{bibhyperref}{default}%
\printnames{labelname}%
\setunit{\printdelim{nameyeardelim}}%
\usebibmacro{cite:labeldate+extradate}}}
{}
{\PackageWarning{biblatex-patch}
{Failed to patch cite bibmacro}}
% Access hyperref's citation link start/end commands
\makeatletter
\protected\def\blx@imc@biblinkstart{%
\@ifnextchar[%]
{\blx@biblinkstart}
{\blx@biblinkstart[\abx@field@entrykey]}}
\def\blx@biblinkstart[#1]{%
\blx@sfsave\hyper@natlinkstart{\the\c@refsection @#1}\blx@sfrest}
\protected\def\blx@imc@biblinkend{%
\blx@sfsave\hyper@natlinkend\blx@sfrest}
\blx@regimcs{\biblinkstart \biblinkend}
\makeatother
\newbool{cbx:link}
% Include parentheses around labelyear in \textcite only in
% single citations without pre- and postnotes
\def\iflinkparens{%
\ifboolexpr{ test {\ifnumequal{\value{multicitetotal}}{0}} and
test {\ifnumequal{\value{citetotal}}{1}} and
test {\iffieldundef{prenote}} and
test {\iffieldundef{postnote}} }}
\xpatchbibmacro{textcite}
{\printnames{labelname}}
{\iflinkparens
{\DeclareFieldAlias{bibhyperref}{default}%
\global\booltrue{cbx:link}\biblinkstart%
\printnames{labelname}}
{\printtext[bibhyperref]{\printnames{labelname}}}}
{}
{\PackageWarning{biblatex-patch}
{Failed to patch textcite bibmacro}}
\xpatchbibmacro{textcite}
{\usebibmacro{cite:label}}
{\iflinkparens
{\DeclareFieldAlias{bibhyperref}{default}%
\global\booltrue{cbx:link}\biblinkstart%
\usebibmacro{cite:label}}
{\usebibmacro{cite:label}}}
{}
{\PackageWarning{biblatex-patch}
{Failed to patch textcite bibmacro}}
\xpretobibmacro{textcite:postnote}
{\ifbool{cbx:link}
{\ifbool{cbx:parens}
{\bibcloseparen\global\boolfalse{cbx:parens}}
{}%
\biblinkend\global\boolfalse{cbx:link}}
{}}
{}
{\PackageWarning{biblatex-patch}
{Failed to patch textcite:postnote bibmacro}}
\renewcommand{\baselinestretch}{1.2}
\setlength{\parskip}{\smallskipamount}
\setlength{\parindent}{0pt}
\addbibresource{biblatex-examples.bib}
\begin{document}
\null\vfill
\textbf{Single citations}
Filler text \parencite{aristotle:poetics}.
Filler text \parencite{kant:ku}. Filler text \parencite{cms}. \\
Filler text \parencite[See][23]{aristotle:poetics}.
Filler text \parencite[1--10]{kant:ku}. \\
\textcite{knuth:ct} and \textcite{knuth:ct:a}.
\textcite{knuth:ct:b} and \textcite{knuth:ct:c}. \\
\textcite{aristotle:poetics} and \textcite{kant:ku} and \textcite{cms}. \\
\textcite[e.g.][]{aristotle:poetics} and \textcite[10]{kant:ku}. \\
Filler text.\footcite[23]{aristotle:poetics} Filler text.\footcite[1--10]{aristotle:rhetoric}
Filler text.\footnote{\smartcite[10--15]{companion}}
\textbf{Unqualified citation lists}
\textcite{knuth:ct,knuth:ct:a,knuth:ct:b,knuth:ct:c} showed that... \\
\textcite[e.g.][10--15]{aristotle:poetics,aristotle:rhetoric,cms} showed that...\\
Filler text \parencite[See][for example]{aristotle:poetics,aristotle:rhetoric,cms}. \\
Filler text \parencite[etc.]{knuth:ct,knuth:ct:a,knuth:ct:b,knuth:ct:c}.
\textbf{Qualified citation lists}
\textcites{aristotle:poetics}{aristotle:rhetoric} showed that...
\textcites(See)(){aristotle:poetics}[cf.][]{aristotle:rhetoric}. \\
\textcites(See)()[e.g.][15]{aristotle:poetics}[cf.][10]{aristotle:rhetoric} \\
\parencites(See)()[10--15]{aristotle:poetics}[cf.][10]{aristotle:rhetoric} \\
\parencites{knuth:ct,knuth:ct:a}[10--11]{knuth:ct:b,knuth:ct:c}
\textbf{Mix of qualified and unqualified citation lists}
\textcites(See)()[e.g.][]{aristotle:poetics}[10]{bertram,companion} \\
\textcites[e.g.][]{aristotle:poetics,aristotle:rhetoric}[10]{companion} \\
\textcites[10]{aristotle:poetics}{aristotle:rhetoric}[cf.][]{bertram} \\
\textcites[15]{aristotle:poetics}[cf.][10]{bertram,companion}
\printbibliography
\chapter*{Appendix}
\end{document}
这是使用 biblatex 2.6 或更早版本时应获得的输出。这些补丁也适用于更高版本,其中\textcite
和朋友将and
字符串合并到最终的引用分隔符中。