カスタム BibLaTeX ライブラリでエントリ `country = {}` が空かどうかを確認するにはどうすればよいですか?

カスタム BibLaTeX ライブラリでエントリ `country = {}` が空かどうかを確認するにはどうすればよいですか?

私はBibLaTeXライブラリを作成し、口頭発表やポスター発表の整理に使用しています。これは実際には新しいデータ型と引用コマンドを備えたカスタマイズされたライブラリです。すべてのアイデアはここそしてここ

しばらくプログラミングした後、次のコードができました。これは非常にうまく機能します。\printcontrib{BiB_entry}任意のテキストで独自のコマンドを使用できますが、たとえば、後者のコマンドを使用してすべての Bib エントリを呼び出すなど、最後にリストを作成することもできます。コードを示す前に、私のコードはおそらく何らかの (悪意のある?) ハックであることをここでお詫びしたいと思います。 ;-)

ムウェ

\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}

出力は次のようになります。 上記のコードの出力

ここまでは順調です。さて、1 つの BibLaTeX エントリ (Oral_2016_1 => Country = {} など) の中には、情報が欠落しているために 2 つの {} 内にテキストがないエントリがいくつかある可能性があります (いくつかの理由により、これらの括弧はそのままにしておきたいことに注意してください...)。

コード内に「if ... do ... else do ...」の部分を入れたいのですが、これはエントリが「空」かどうかをチェックするものなので、ここでは ですCountry = {}。それ以外の場合は、ここでの場合のように、テキストに 2 つの括弧 () が表示されます。

特にこのコマンドで、この if 条件を設定したいと思います。

% 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})
} 

コマンド(括弧に(\citecountry{#1})注意) は、エントリにテキストが含まれている場合、つまりBibLaTeX ファイルに含まれていない場合にのみ実行されます。()countryCountry = {}

いろいろ試してみました。たとえば、、、パッケージの助けを借りていくつかの if 条件を試しましたがifmtarg、成功しませんでした。% 引用符 (MWE のテキストの下) 内のみは、多少は機能しますが、エラーが発生します (LaTeX でコンパイルされるように、これをコメント解除する必要があります)。xstringifthenhalf-solution% Here is my first test

答え1

ではbiblatex、括弧や強調、斜体などのフィールド書式設定は、ほとんどの場合、マクロに直接書き込むべきではなく、 を使用して実現する必要があります。 こうすることで、 が空のフィールドを適切に検出し、その場合には何もしないことが\DeclareFieldFormat保証されます。biblatex

ただこうすればいい

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

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

フィールドは、表示されるときは常に括弧で囲まれ、それ以外の場合は無視されます。引数なしで単一の\printfieldを に囲む必要はなく、と同じ動作をすることに注意してください。\printtext\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

ここに画像の説明を入力してください

関連情報