Biblatex 中的 If 语句

Biblatex 中的 If 语句

在花了很多时间仔细研究示例和文档后,我终于得到了几乎满足我要求的参考资料(耶!)。仍有一些我无法处理的部分,我希望你们这些 TeX 巨头能够提供帮助!:) 在底部我给出了一个“最小”工作示例...但它并不短,所以我将尝试在这里总结一些问题。大部分归结为期望if/then语句。可能我需要使用xifthen?(我正在使用DeclareBibliographyDriver.)

(1)我的一些物品有卷号和期号。在这种情况下,我想将其写为“体积.问题”,例如3.2. 我已经使用 完成了此操作\printfield{volume}\addperiod\printfield{number}。当有卷号和发行号时,这没问题,但如果没有,它会打印一个句号 (.),这是我不想要的。所以我想说

\printfield{volume}
if {'number' exists (as a field)} then {\addperiod\printfield{number}}

同样,我想将页码打印在括号中,例如 (112--114)。同样,我可以使用\printtext[parens]{\printfield{pages}},但如果没有页码,这只会给出一对空括号 (),而我并不需要。所以我想说

if {'pages' exists} then {\printtext[parens]{\printfield{pages}}}

我知道通常的做法是不要在同一个帖子中提出两个问题,但考虑到这些问题非常相似,并且它们(希望)应该能够一起得到回答,我觉得最好这样写。


我现在给出一个 MWE 和一个输出的快照。

\documentclass[]{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@article{FR:giant-mixing,
    title = {The Evolution of the Mixing Rate of a Simple Random Walk on the Giant Component of a Random Graph},
    volume = {33},
    number = {1},
    journaltitle = {Random Structures \& Algorithms},
    urldate = {2018-03-22},
    date = {2008-05-12},
    pages = {68-86},
    author = {Fountoulakis, Nikolaos and Reed, Bruce A.}
}
@article{AGHH:dynamic-cm,
    archivePrefix = {arXiv},
    eprinttype = {arxiv},
    eprint = {1606.07639},
    title = {Mixing Times of Random Walks on Dynamic Configuration Models},
    date = {2016-06-24},
    author = {Avena, Luca and G{\"u}lda{\c s}, Hakan and van der Hofstad, Remco and den Hollander, Frank},
    options = {useprefix=true}
}
\end{filecontents}

\usepackage{csquotes}
\usepackage[hyperref=true,backend=biber,style=numeric]{biblatex}
\addbibresource{\jobname.bib}

\DeclareFieldFormat
    [article,book]
    {volume}{\textbf{#1}}
\DeclareFieldFormat
    {pages}{#1}

\DeclareBibliographyDriver{article}{%
    \printnames{author}%
\   \newblock
    \printtext[parens]{\printfield{year}}\addperiod%
    \newunit
    \printfield{title}
    \newunit\newblock
    \printfield{journaltitle}%
    \printfield{eprint}%\addperiod%
\   \newblock
    \printfield{volume}\addperiod\printfield{number}%
\   \newblock
    \printtext[parens]{\printfield{pages}}%
}


\begin{document}

Document...

\nocite{*}
\printbibliography

\end{document}

在此处输入图片描述

答案1

biblatex有几个条件可用。其中之一是\iffieldundef{<field>}检查字段是否未定义(如果字段为空,则通常未定义)。因此您可以使用

\iffieldundef{number}
  {}%                              <- do nothing if number does not exist
  {\addperiod\printfield{number}}% <- number exists: print it

不过,我觉得你的情况实际上并不需要\iffieldundef。相反,你会想要看看两个非常重要的biblatex风格概念

  • 字段格式\DeclareFieldFormat
  • 标点符号追踪器

让我们举\printtext[parens]{\printfield{pages}}个例子:你想在括号中打印页码。但是,正如你所注意到的,如果字段pages为空,这行代码实际上会给你一对空的圆括号。这是因为\printtext[parens]即使参数为空,它也会简单地用圆括号将其参数包裹起来。使用我们的,\iffieldundef你可以写\iffieldundef{pages}{}{\printtext[parens]{\printfield{pages}}}。但有一种更优雅的方式:

定义您想要看到的圆括号中pages@article

 \DeclareFieldFormat[article]{pages}{\mkbibparens{#1}}

然后只需使用

 \printfield{pages}

第一行告诉您biblatex将页码放在括号中,第二行告诉您biblatex打印页码。如果pages不存在该字段,则不会发生任何事情。

可以对年份做类似的事情,但biblatex处理日期的设置更复杂,因此稍微复杂一些。我可能会选择

\DeclareFieldFormat[article]{date}{\mkbibparens{#1}}

对于格式然后\printdate或更好

\usebibmacro{date}

标点符号跟踪器使处理标点符号和空格变得更加容易。您不必使用和\iffieldundef之间的点,也不必使用来提供空格。volumenumber\

追踪器的解释见§4.11.7使用标点符号追踪器biblatex文档。本节有几页长(这个答案也是如此……),但它附带了许多示例,绝对值得一读。标点符号跟踪器的想法是它biblatex不会立即打印它遇到的任何标点符号,而是记住标点符号并在下次打印文本时插入它。这避免了双重标点符号。本节的第一个要点是,您几乎总是希望使用\setunit标点符号,标点符号命令应该很少出现在之外\setunit

\setunit接受提供的标点符号命令并将其保存在标点符号缓冲区中。缓冲区将被使用,并在下次biblatex打印任何内容时清除(使用\print...)。后续的\setunits 将覆盖缓冲区。

所以你可以说

\printfield{eprint}%
\setunit{\addspace}\newblock
\printfield{pages}%

打印eprint字段,然后打印空格,最后打印pages字段。如果两个字段中有一个未打印,您也不会遇到麻烦。

两个字段之间的常用标点符号是\newunit\newblock。本质上是对 中定义的标点符号\newunit执行并添加一个内部标记,表示新块/“块”从此处开始。可以使用选项修改块的行为。\setunit\newunitpunct\newblockblock

使用标点符号跟踪器\printfield{volume}\addperiod\printfield{number}%将变得

\printfield{volume}%
\setunit*{\adddot}
\printfield{number}%

这里我们使用了带星号的版本\setunit*,它只会在它之前的最后一个\print...命令执行了任何操作时才将值插入到缓冲区中(因此它就像\setunit添加了一个检查:如果最后一个命令\print...打印了任何内容,则\setunit*其行为与完全相同\setunit,否则它将丢弃其参数)。因此,如果缓冲区为空,则不会将点插入到缓冲区中volume


如果你编写了参考书目驱动程序,那么尝试以 中的标准驱动程序为模型是一个好主意standard.bbx。 中的驱动程序standard.bbx实际上并不\print...直接调用许多指令,而是调用其他 bibmacros 来执行此操作。驱动程序应始终调用两个宏bibindexbegentry指令,而是调用其他 bibmacros 来执行此操作。驱动程序应始终在开头和结尾处必须finentry最后调用。bibmacrofinentry调用\finentry执行一些清理工作的宏。

您的设置可能看起来像

\DeclareFieldFormat[article]{date}{\mkbibparens{#1}}
\DeclareFieldFormat[article,book]{volume}{\mkbibbold{#1}}
\DeclareFieldFormat[article]{pages}{\mkbibparens{#1}}

\renewbibmacro*{volume+number+eid}{%
  \printfield{volume}%
  \setunit*{\adddot}%
  \printfield{number}%
  \setunit{\addcomma\space}%
  \printfield{eid}}

\DeclareBibliographyDriver{article}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \usebibmacro{author}%
  \setunit{\addspace}%
  \usebibmacro{date}%
  \newunit\newblock
  \usebibmacro{title}%
  \newunit\newblock
  \printfield{journaltitle}%
  \setunit{\addspace}%
  \usebibmacro{volume+number+eid}%
  \newunit\newblock
  \usebibmacro{eprint}%
  \setunit{\addspace}\newblock
  \printfield{pages}%
  \usebibmacro{finentry}%
}

事实上,这可以改变得更像驾驶员@articlestandard.bbx但这样就会隐藏更多的东西。

事实上,我相信您只需更改 bibmacros 和使用一些狡猾的诡计就可以获得所需的输出,而无需重新定义单个驱动程序。


最后,我想说说我最喜欢的几个biblatex讨厌的事情

  • 该选项hyperref=true通常不比默认的更好hyperref=auto。两者之间的唯一区别是,如果未加载,则会hyperref=true向文件写入警告。除此之外,它们的行为完全相同。特别是,当且仅当加载时,两者才会启用超链接。.loghyperrefhyperref

  • 在 arXiv 上发表但未在任何期刊上发表的论文不是条目@article- 它是一个@online条目。只有实际具有非空字段的论文journal才可以被@article收录。请参阅biblatex 书目条目中没有期刊标题字段的 @article 格式

相关内容