8

I have created a BibLaTeX library, which I use to organize all my oral and poster presentations. It is in fact a customized library with new data types and cite commands. I got all ideas from here and here.

After some time of programming, I got the following code, which works quite well. I can use my own command \printcontrib{BiB_entry} in any text, but also I can do some listing at the end by, e.g., calling all Bib entries via the latter command. Before I show the code, I would like to apologize already here that my code is probably some (evil?) hack. ;-)

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}

The output looks like this: The output of the code from above

So far so good. Now, there might be some entries in one BibLaTeX entry (see, e.g., Oral_2016_1 => Country = {}), that have no text inside the two {} because some info is missing (note that I would like to keep these brackets due to a couple of reasons ... .)

I would like to have a 'if ... do ... else do ...' part in the code, which checks if an entry is 'empty', so here Country = {}. Otherwise, as it is the case here, the are two brackets displayed in the text ().

I would like to have this if conditioning in particular in this command:

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

The (\citecountry{#1}) command (note the ( and ) brackets) shall be only executed, if the entry country has some text, in other words, is not Country = {} in the BibLaTeX file.

I tried out a dozen of things. For instance, I tried several if conditions with help of the ifmtarg, xstring and ifthen packages but without any success. The only half-solution in the % quotation (below the text % Here is my first test in the MWE) somewhat works, however, with errors (you have to uncomment this such that it is compiled by LaTeX).

0

2 Answers 2

3

In biblatex, field formatting such as brackets or emphasis or italics should not be written into the macro directly in most cases, they should be achieved with \DeclareFieldFormat. That way you make sure that biblatex can properly detect empty fields and do nothing in that case.

You could just do

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

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

The field is then wrapped in brackets whenever it is shown and ignored otherwise. Note that there is no need to wrap a single \printfield into a \printtext without argument, \printfield{country} will do the same as \printtext{\printfield{country}}.

Instead of defining \citecontrib as you do now, you should probably just define a bibliography driver for @contribution like so (this is just a first rough shot at this, but you get the idea)

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

Then you can just use \fullcite and you are done.

3
  • For moewe: Question: If I work with '\newbibmacro' and '\DeclareBibliographyDriver' I automatically agree to all styles that are described in, e.g., '\usepackage[...]{biblatex}', '\documentclass' ... . E.g., the type of style for author and title can be changed by using '\usepackage[style=chem-acs]{biblatex}'. Furthermore date can be changed from '\documentclass[american]{book}' to '\documentclass[english]{book}'. So, If I want this I would do it. However, if I want to keep a specific style I rather make use of '\DeclareFieldFormat' and '\DeclareCiteCommand'. Is that right?
    – Krumpel
    Commented Jan 26, 2017 at 8:52
  • @Krumpel I'm not entirely sure if I follow you, but I don't think you can say that in all generality. \newbibmacro, \DeclareBibliographyDriver, \DeclareFieldFormat and \DeclareCiteCommand do different things and work at different code levels. Which is prerenal depends on what exactly you want to achieve. It is true that \newbibmacro and \DeclareBibliographyDriver use the formats declared by \DeclareFieldFormat, expect if you explicitly disable that.
    – moewe
    Commented Jan 26, 2017 at 17:34
  • \@ moewe: Sorry for having confused you. It has taken a rather long time for me to understand, how things work in BibLaTeX. On that day, I was quite confused. Things are clear now, thx for your help. Later, I will show my solution ... .
    – Krumpel
    Commented Jan 30, 2017 at 10:28
4

You should check whether the field exists as part of the \DeclareCiteCommand using \iffieldundef (or something similar; see section 4.6.2 Stand-alone Tests in the biblatex documentation):

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

and here is \printcontrib:

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

You may also write a larger \DeclareCiteCommand rather using \printcontrib.

enter image description here

4
  • Perfect (+100 points) and thanks a lot! - In fact, I also tried this directly in the '\DeclareCiteCommand' environment with '\iffieldundef' but I got somewhat lost. And yes, I will consider 'You may also write a larger \DeclareCiteCommand rather using \printcontrib.', I will report on this - Question: in my code, how can I change '\DeclareCiteCommand*{\citeauthor}' such that LaTeX uses the style specified in '\usepackage[..., style=chem-acs,', ...]'?
    – Krumpel
    Commented Jan 21, 2017 at 23:15
  • @Krumpel: Ask a follow-up question.
    – Werner
    Commented Jan 21, 2017 at 23:20
  • Okay, I didn't know. - Thanks a lot for your very quick help that has lead to a rolling stone: I'm currently exploring the vast possibilities of CV data automation in research via TeX/LaTeX/BibLaTeX/Python and without using MSWord etc.! When I have a suitable hack, I will present it here ... .
    – Krumpel
    Commented Jan 21, 2017 at 23:46
  • Please note that writing cite commands as \printcontrib with \newcommand by sticking several \cite... together is really bad style in biblatex. A command like this will not be able at all to handle pre or postnotes and multiple citations properly without much extra work, one should always use \DeclareCiteCommand.
    – moewe
    Commented Jan 25, 2017 at 8:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .