使用变量作为 BIBER DATE 值会在输出中产生空白日期

使用变量作为 BIBER DATE 值会在输出中产生空白日期

我正在使用 MikTex 和 biber

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

我想使用变量来存储日期值,但它不提供任何输出。我在文件中设置了 biber 类别和变量,如下所示QMSbiblatex.tex

\addtocategory{MILinternal}{ref__MIL_QAM_QualityAssuranceManual}
\newcommand{\RepsSopQualityAssuranceManualNumber}{MIL-QAM-9001}
\newcommand{\RepsSopQualityAssuranceManualTitle}{REPS Quality Assurance Manual - ISO 9001}
\newcommand{\RepsSopQualityAssuranceManualDate}{2017-07-13}

然后将引用定义references.bib

@Electronic{ref__MIL_QAM_QualityAssuranceManual,
  author       = {\RepsSopQualityAssuranceManualNumber},
  organization = {{\RepsCitationOrganization}},
  title        = {{\RepsSopQualityAssuranceManualTitle}},
  date         = {\RepsSopQualityAssuranceManualDate},
}

其中不包括参考日期,但

@Electronic{ref__MIL_QAM_QualityAssuranceManual,
  author       = {\RepsSopQualityAssuranceManualNumber},
  organization = {{\RepsCitationOrganization}},
  title        = {{\RepsSopQualityAssuranceManualTitle}},
  date         = {2017-07-13},
}

按预期输出带有日期的参考。

为什么使用变量在 DATE 字段中不起作用但在其他字段中却可以起作用?

答案1

要理解为什么这没有像你希望的那样发挥作用,我们首先需要了解.bib文件的工作原理。使用问号或粗体引用关键字代替引用编号对 BibTeX 和 Biber 的工作进行了很好的解释。简而言之(但请也阅读 Paul Stanley 的回答,它很棒),Biber(和 BibTeX,但从现在开始我只说 Biber)解析文件.bib并生成可用于 LaTeX 的输出。因为biblatexBiber(后端)生成的输出是结构化的、LaTeX 可读的、预简化和增强的输入数据版本。

Biber 精简版条目

@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {1980-04-06},
}

可能看起来像这样

\entry{appleby}{book}{}
  \name{author}{1}{}{%
    {{uniquename=0,uniquepart=base,hash=dd90e644e3018ab2c6a7ffa2a58522d0}{%
       family={Appleby},
       familyi={A\bibinitperiod},
       given={Humphrey},
       giveni={H\bibinitperiod},
       givenun=0}}%
  }
  \list{location}{1}{%
    {London}%
  }
  \list{publisher}{1}{%
    {Routledge}%
  }
  \strng{namehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{fullhash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{bibnamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authorbibnamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authornamehash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \strng{authorfullhash}{dd90e644e3018ab2c6a7ffa2a58522d0}
  \field{sortinit}{A}
  \field{sortinithash}{d77c7cdd82ff690d4c3ef13216f92f0b}
  \field{extradatescope}{labelyear}
  \field{labeldatesource}{}
  \field{labelnamesource}{author}
  \field{labeltitlesource}{title}
  \field{day}{6}
  \field{month}{4}
  \field{title}{On the Importance of the Civil Service}
  \field{year}{1980}
  \field{dateera}{ce}
\endentry

请注意,Biber 已处理某些字段。特别是,名称Humphrey Appleby已拆分为两个部分,Biber 已生成名称哈希。条目Appleby, Humphrey中的.bib将产生完全相同的结果。同样,date = {1980-04-06},已解析并分解为其日期部分(\field{year}{1980}\field{month}{4}\field{day}{6}、...)。

值得注意的是,Biber 和 BibTeX 不是 LaTeX,它们不理解或解析 LaTeX 宏。

title     = {\foo},

就会变成

  \field{title}{\foo}

(Biber 实际上知道一些LaTeX 宏,即一些解析为 Unicode 字符的宏,但这对我们没有帮助。)

宏只是传递的,只有当数据在文档中使用时才会使用(扩展)。具体来说,这意味着

date         = {\RepsSopQualityAssuranceManualDate},

文件中的.bib信息无法被 Biber 解析,因为

\newcommand{\RepsSopQualityAssuranceManualDate}{2017-07-13}

仅在文档中可用.tex,Biber 无法访问。因此 Biber 只会看到\RepsSopQualityAssuranceManualDate哪些日期无效,并在.blg文件中将其丢弃并提出投诉。

WARN - Entry 'ref__MIL_QAM_QualityAssuranceManual' (test.bib):
       Invalid format '\RepsSopQualityAssuranceManualDate' of date field 'date' - ignoring

类似的事情也会发生在名称字段上。如果我们写

author    = {\appleby},

.bib和定义

\newcommand*{\appleby}{Humphrey Appleby}

.tex文件中,我们最终会得到

  \name{author}{1}{}{%
    {{uniquename=0,uniquepart=base,hash=0213062b7acb78617f5861ef3be11354}{%
       family={\appleby},
       familyi={y\bibinitperiod}}}%
  }

在 中.bbl。这表明 Biber 并未将姓名解析为由姓氏“Appleby”和名字“Humphrey”组成。相反,它仅由家庭部分组成\appleby(扩展为“Humphrey Appleby”)。所有依赖于biblatex了解名字和姓氏部分的功能都不会按预期工作,“Humphrey Appleby”将被视为原子单位。例如,在作者年份引文中,我们会得到“Humphrey Appley 1980”而不是“Appleby 1980”。

这表明您不能使用 TeX 宏/变量来填充.bib条目中的字段,这些字段必须由 Biber 进行解析。


所以,你可以做什么?

这很大程度上取决于您的使用情况。

第一个问题可能是您是否需要这样的条目。您引用的作品的书目数据会发生变化,需要您在文档中动态修改数据,这似乎有点奇怪。

第二种尝试可能是反转信息流。根据您考虑的用例,可能只需在文件中输入一次数据,然后使用、、或甚至、、 ... 等.bib检索某些位就足够了。但是,这些命令不可扩展,因此如果您需要以可扩展的方式获取数据,则需要采取略有不同的方法(这仍然可能是可能的,如果您有兴趣,您可能应该问一个新问题,不过,这个答案已经够长了)。\citetle{ref__MIL_QAM_QualityAssuranceManual}\citeauthor{ref__MIL_QAM_QualityAssuranceManual}\citedate{ref__MIL_QAM_QualityAssuranceManual}\citefield{ref__MIL_QAM_QualityAssuranceManual}{title}\citelist{ref__MIL_QAM_QualityAssuranceManual}{organization}\cite...

如果您需要根据文档动态创建包含数据的条目,那么您可以随时使用filecontents

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {1980-04-06},
}
\end{filecontents}

\addbibresource{\jobname.bib}

\begin{document}
\cite{appleby}
\printbibliography
\end{document}

.bib文件知道@string可以用来存储重复或可能改变的信息。@string甚至可以从不同的文件中获取.bib,因此你可以执行以下操作

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname-entry.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = mydate,
}
\end{filecontents}
\begin{filecontents}{\jobname-strings.bib}
@string{mydate = {1980-06-05}}
\end{filecontents}

\addbibresource{\jobname-strings.bib}
\addbibresource{\jobname-entry.bib}


\begin{document}
\cite{appleby}
\printbibliography
\end{document}

您还可以使用源映射来操作字段数据。由于源映射的工作方式,宏将在此\replace步骤中展开,因此您甚至可以在此处使用宏。

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[backend=biber,natbib=true,style=numeric,sorting=none]{biblatex}

\newcommand*{\applebydate}{1980-07-08}
\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map{
      \step[fieldsource=date,
            match=\regexp{\A\\applebydate\Z},
            replace=\applebydate]
    }
  }
}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{appleby,
  author    = {Humphrey Appleby},
  title     = {On the Importance of the Civil Service},
  location  = {London},
  publisher = {Routledge},
  date      = {\applebydate},
}
\end{filecontents}

\addbibresource{\jobname.bib}


\begin{document}
\cite{appleby}
\printbibliography
\end{document}

相关内容