如何驗證自訂 BibLaTeX 庫中的條目“country = {}”是否為空?

如何驗證自訂 BibLaTeX 庫中的條目“country = {}”是否為空?

我創建了一個 BibLaTeX 庫,用它來組織我所有的口頭和海報演示。它實際上是一個具有新資料類型和引用命令的自訂庫。我的所有想法都來自這裡這裡

經過一段時間的編程,我得到了以下代碼,效果很好。我可以在任何文字中使用我自己的命令\printcontrib{BiB_entry},但我也可以在最後進行一些列表,例如透過後一個命令呼叫所有書目條目。在展示程式碼之前,我想在這裡道歉,我的程式碼可能是某種(邪惡的?)駭客行為。 ;-)

微量元素

\RequirePackage{filecontents}


% The BibTeX library
\begin{filecontents*}{\jobname.bib}
@Contribution{Oral_2016_1,
  Type      = {Oral},
  Invited   = {True},
  Author    = {{\textbf{Author, One} and Author, Two and Author, Three}},
  Presenter = {{Author, One}},
  Title     = {{Some cool stuff about the Nanoworld}},
  Event     = {{Conference about XYZ}},
  Eventtype = {Conference},
  Place     = {},
  City      = {Helsinki (Finland) - Stockholm (Sweden)},
  Country   = {},
  Date      = {May 1$^{\rm st}$ - June 2$^{\rm nd}$},
  Period    = {},
  Year      = {2016},
  Note      = {}
}

@Contribution{Oral_2015_1,
  Type      = {Oral},
  Invited   = {Ture},
  Author    = {{\textbf{Author, One}}},
  Presenter = {{Author, One}},
  Title     = {{Exciting research on cool Nanostuff}},
  Event     = {{6$^{\rm th}$ Nanotechnology workshop}},
  Eventtype = {Workshop},
  Place     = {},
  City      = {Giessen},
  Country   = {Germany},
  Date      = {September 24$^{\rm th}$},
  Period    = {},
  Year      = {2015},
  Note      = {}
}

@Contribution{Oral_2015_2,
  Type      = {Oral},
  Invited   = {False},
  Author    = {{Author, One and Author, Two and \textbf{Author, Three}}},
  Presenter = {{Author, Three}},
  Title     = {{Nanochemistry at its edge}},
  Event     = {{18$^{\rm th}$ Summer School of Nanochemistry}},
  Eventtype = {School},
  Place     = {},
  City      = {Cassis},
  Country   = {France},
  Date      = {September 9$^{\rm th}$},
  Period    = {},
  Year      = {2015},
  Note      = {}
}
\end{filecontents*}

% The declaration of the entries.
\begin{filecontents}{contribution.dbx}
\DeclareDatamodelEntrytypes{contribution}
\DeclareDatamodelFields[type=field,datatype=literal]{
  type,
  invited,
  title,
  event,
  eventtype,
  place,
  city,
  country,
  date,
  period,
  year,
  note
}

\DeclareDatamodelFields[type=list,datatype=name]{
  author,
  presenter
}
\DeclareDatamodelEntryfields[contribution]{
  type,
  invited,
  author,
  presenter,
  title,
  event,
  eventtype,
  place,
  city,
  country,
  date,
  period,
  year,
  note}
\end{filecontents}



% The standard LaTeX head, with a link to the chem-acs style and biber. The
% datamodel 'contribution' is also declared.
\documentclass[english]{book}
\usepackage{babel}
\usepackage{ifmtarg}
\usepackage{xstring}
\usepackage{ifthen}
\usepackage[datamodel=contribution,
            style=chem-acs,
            natbib=true,
            backend=biber]
           {biblatex}
\addbibresource{\jobname.bib}



% Declare cite commands, the most important ones. Others will be added.
\DeclareCiteCommand{\citeevent}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{event}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\citedate}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{date}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\citeyear}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{year}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\citecity}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{city}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\citecountry}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{country}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand{\citetitle}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printtext{\printfield{title}}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

\DeclareCiteCommand*{\citeauthor}
    {\defcounter{maxnames}{99}%
     \defcounter{minnames}{99}%
     \defcounter{uniquename}{2}%
     \boolfalse{citetracker}%
     \boolfalse{pagetracker}%
     \usebibmacro{prenote}}
    {\ifciteindex{\indexnames{labelname}}{}\printnames{labelname}}
    {\multicitedelim}
    {\usebibmacro{postnote}}




% My own command, which puts into format and prints the contribution.
\newcommand{\printcontrib}[1]{
    \citeauthor*{#1}, 
    \citetitle*{#1}, 
    \citeevent{#1},
    \citecity{#1} 
%
%   This works, but there is no 'if' that might find an empty 'country' field.
%   I would like to have:
%   If  : Country   = {} => Do not print '(\citecountry{#1})' 
%   Else: print (\citecountry{#1})
    (\citecountry{#1}),
%
%
%   Here is my first test amongst many others:
%   It works but there is a error: "! Illegal unit of measure (pt inserted)." 
%
%   \newlength{\strlen}\settowidth{\strlen}{\citecountry{#1}}
%   \ifdim\strlen=0\else(\citecountry{#1})\fi,
%   \let\strlen\relax 
%    
    \citedate{#1} (\citeyear{#1})
} 




\begin{document}

\chapter{Oral contributions}

\printcontrib{Oral_2016_1}\\\\
%
\noindent\printcontrib{Oral_2015_2}\\\\
%
\noindent\printcontrib{Oral_2015_1}\\\\
%

\end{document}

輸出如下圖所示: 上面程式碼的輸出

到目前為止,一切都很好。現在,一個 BibLaTeX 條目中可能有一些條目(例如,Oral_2016_1 => Country = {}),在兩個 {} 內沒有文本,因為缺少一些信息(請注意,我想保留這些括號有幾個原因.. ....)

我希望程式碼中有一個“if ... do ... else do ...”部分,它檢查條目是否為“空”,所以這裡Country = {}。否則,就像這裡的情況一樣,文字中顯示的是兩個括號 ()。

我希望在這個命令中特別是條件化:

% My own command, which puts into format and prints the contribution.
\newcommand{\printcontrib}[1]{
    \citeauthor*{#1}, 
    \citetitle*{#1}, 
    \citeevent{#1},
    \citecity{#1} 
%
%   This works, but there is no 'if' that might find an empty 'country' field.
%   I would like to have:
%   If  : Country   = {} => Do not print '(\citecountry{#1})' 
%   Else: print (\citecountry{#1})
    (\citecountry{#1}),
%
%
%   Here is my first test amongst many others:
%   It works but there is a error: "! Illegal unit of measure (pt inserted)." 
%
%   \newlength{\strlen}\settowidth{\strlen}{\citecountry{#1}}
%   \ifdim\strlen=0\else(\citecountry{#1})\fi,
%   \let\strlen\relax 
%    
    \citedate{#1} (\citeyear{#1})
} 

只有當條目包含某些文字(換句話說,不在BibLaTeX 檔案中)時,才應執行該(\citecountry{#1})命令(請注意(和括號)。)countryCountry = {}

我嘗試了十幾件事。例如,我在ifmtarg,xstringifthen包的幫助下嘗試了幾個 if 條件,但沒有成功。 % 引用中的唯一內容half-solution(在 MWE 中的文本下方% Here is my first test)有些工作,但有錯誤(您必須取消註釋它,以便它由 LaTeX 編譯)。

答案1

在 中biblatex,欄位格式(如括號、強調或斜體)在大多數情況下不應直接寫入巨集,而應使用 來實現\DeclareFieldFormat。這樣您就可以確保biblatex可以正確檢測空字段,並且在這種情況下不執行任何操作。

你可以這樣做

\DeclareFieldFormat{country}{\mkbibparens{#1}}

\DeclareCiteCommand{\citecountry}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\printfield{country}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

然後,每當顯示該欄位時,該欄位就會用括號括起來,否則會被忽略。請注意,無需將 single 包裝\printfield\printtext不含參數的 a,\printfield{country}將與 執行相同的操作\printtext{\printfield{country}}

您可能應該像這樣定義一個參考書目驅動程序,而不是\citecontrib像現在這樣定義@contribution(這只是第一個粗略的嘗試,但您明白了)

\DeclareFieldFormat{country}{\mkbibparens{#1}}
\DeclareFieldFormat[contribution]{title}{\mkbibemph{#1}}

\newbibmacro*{event+venue+city+country+date}{%
  \printfield{eventtitle}%
  \newunit
  \printfield{eventtitleaddon}%
  \newunit
  \printeventdate
  \newunit
  \printfield{city}
  \setunit{\addspace}%
  \printfield{country}
  \newunit}

\DeclareBibliographyDriver{contribution}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \usebibmacro{author/editor+others/translator+others}%
  \setunit{\printdelim{nametitledelim}}\newblock
  \usebibmacro{title}%
  \newunit
  \printlist{language}%
  \newunit\newblock
  \usebibmacro{byauthor}%
  \newunit\newblock
  \usebibmacro{event+venue+city+country+date}%
  \newunit\newblock
  \printfield{howpublished}%
  \newunit\newblock
  \printfield{note}%
  \newunit\newblock
  \usebibmacro{location+date}\printdate%
  \newunit\newblock
  \iftoggle{bbx:url}
    {\usebibmacro{url+urldate}}
    {}%
  \newunit\newblock
  \usebibmacro{addendum+pubstate}%
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

然後你就可以使用了\fullcite,就完成了。

答案2

您應該檢查該欄位是否作為\DeclareCiteCommandusing的一部分存在\iffieldundef(或類似的內容;請參閱部分4.6.2 獨立測試在裡面biblatex 文件):

\DeclareCiteCommand{\citecountry}
  {\boolfalse{citetracker}%
   \boolfalse{pagetracker}%
   \usebibmacro{prenote}}
  {\iffieldundef{country}{}{(\printtext{\printfield{country}})}}
  {\multicitedelim}
  {\usebibmacro{postnote}}

這是\printcontrib

\newcommand{\printcontrib}[1]{%
  \citeauthor*{#1}, 
  \citetitle*{#1}, 
  \citeevent{#1},
  \citecity{#1} 
  \citecountry{#1},
  \citedate{#1} (\citeyear{#1})
} 

您也可以編寫一個更大的\DeclareCiteCommand而不是使用\printcontrib.

在此輸入影像描述

相關內容