Wie überprüfe ich, ob der Eintrag „country = {}“ in einer benutzerdefinierten BibLaTeX-Bibliothek leer ist?

Wie überprüfe ich, ob der Eintrag „country = {}“ in einer benutzerdefinierten BibLaTeX-Bibliothek leer ist?

Ich habe eine BibLaTeX-Bibliothek erstellt, die ich zur Organisation aller meiner mündlichen und Posterpräsentationen verwende. Es handelt sich tatsächlich um eine angepasste Bibliothek mit neuen Datentypen und Zitierbefehlen. Alle Ideen habe ich vonHierUndHier.

Nach einiger Programmierzeit habe ich nun folgenden Code erhalten, der ganz gut funktioniert. Ich kann \printcontrib{BiB_entry}in jeden Text eigene Befehle einfügen, aber auch am Ende eine Auflistung machen, indem ich beispielsweise alle Bib-Einträge über den letzten Befehl aufrufe. Bevor ich den Code zeige, möchte ich mich schon hier entschuldigen, dass es sich bei meinem Code wahrscheinlich um einen (bösen?) Hack handelt. ;-)

MWE

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

Die Ausgabe sieht folgendermaßen aus: Die Ausgabe des Codes von oben

So weit, so gut. Nun kann es in einem BibLaTeX-Eintrag einige Einträge geben (siehe z. B. Oral_2016_1 => Country = {}), die keinen Text innerhalb der beiden {} haben, weil Informationen fehlen (beachten Sie, dass ich diese Klammern aus mehreren Gründen beibehalten möchte ... .)

Ich hätte gerne einen 'if...do...else do...' Teil im Code, der prüft ob ein Eintrag 'leer' ist, also hier Country = {}. Andernfalls, wie es hier der Fall ist, werden im Text zwei Klammern angezeigt ().

Diese if-Konditionierung hätte ich insbesondere gerne in diesem Befehl:

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

Der (\citecountry{#1})Befehl (beachten Sie die Klammern (und )) soll nur ausgeführt werden, wenn der Eintrag countryText enthält, also nicht Country = {}in der BibLaTeX-Datei enthalten ist.

Ich habe ein Dutzend Dinge ausprobiert. Ich habe zum Beispiel mehrere if-Bedingungen mit Hilfe der Pakete ifmtarg, xstringund ausprobiert ifthen, aber ohne Erfolg. Einzig half-solutiondas %-Zitat (unter dem Text % Here is my first testim MWE) funktioniert einigermaßen, allerdings mit Fehlern (dieses muss man auskommentieren, damit es von LaTeX kompiliert wird).

Antwort1

In biblatexsollten Feldformatierungen wie Klammern, Hervorhebungen oder Kursivschrift in den meisten Fällen nicht direkt in das Makro geschrieben werden, sondern mit erfolgen \DeclareFieldFormat. Auf diese Weise stellen Sie sicher, dass biblatexleere Felder richtig erkannt werden und in diesem Fall nichts unternommen wird.

Du könntest einfach

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

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

\printfieldDas Feld wird dann in Klammern gesetzt, wann immer es angezeigt wird, und andernfalls ignoriert. Beachten Sie, dass es nicht notwendig ist, ein einzelnes in ein \printtextohne Argument zu setzen , \printfield{country}es bewirkt dasselbe wie \printtext{\printfield{country}}.

Anstatt es so zu definieren \citecontrib, wie Sie es jetzt tun, sollten Sie wahrscheinlich einfach einen Bibliographietreiber wie @contributionfolgt definieren (das ist nur ein erster grober Versuch, aber Sie verstehen, was ich meine):

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

Anschließend einfach verwenden \fullciteund fertig.

Antwort2

Sie sollten prüfen, ob das Feld als Teil des \DeclareCiteCommandusing \iffieldundef(oder etwas Ähnlichem) existiert (siehe Abschnitt4.6.2 Stand-Alone-Testsimbiblatex Dokumentation):

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

und hier ist \printcontrib:

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

Sie können \DeclareCiteCommandstattdessen auch einen größeren Wert schreiben \printcontrib.

Bildbeschreibung hier eingeben

verwandte Informationen