He creado una biblioteca BibLaTeX, que utilizo para organizar todas mis presentaciones orales y pósteres. De hecho, es una biblioteca personalizada con nuevos tipos de datos y comandos de cita. Saqué todas las ideas deaquíyaquí.
Después de un tiempo de programación, obtuve el siguiente código, que funciona bastante bien. Puedo usar mi propio comando \printcontrib{BiB_entry}
en cualquier texto, pero también puedo hacer una lista al final, por ejemplo, llamando a todas las entradas Bib mediante el último comando. Antes de mostrar el código, me gustaría disculparme porque mi código probablemente sea algún truco (¿malvado?). ;-)
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}
Hasta ahora, todo bien. Ahora, puede haber algunas entradas en una entrada de BibLaTeX (ver, por ejemplo, Oral_2016_1 => País = {}), que no tienen texto dentro de los dos {} porque falta algo de información (tenga en cuenta que me gustaría mantener estos corchetes debido por un par de razones... .)
Me gustaría tener una parte 'if... do... else do...' en el código, que verifica si una entrada está 'vacía', así que aquí Country = {}
. De lo contrario, como es el caso aquí, se muestran dos corchetes en el texto ().
Me gustaría tener este if condicionado en particular en este comando:
% 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})
}
El (\citecountry{#1})
comando (tenga en cuenta los corchetes (
y )
) solo se ejecutará si la entrada country
tiene algún texto, es decir, no está Country = {}
en el archivo BibLaTeX.
Probé una docena de cosas. Por ejemplo, probé varias condiciones if con la ayuda de los paquetes ifmtarg
, xstring
y ifthen
pero sin éxito. El único half-solution
en la cita % (debajo del texto % Here is my first test
en MWE) funciona un poco, sin embargo, con errores (debe descomentarlo para que sea compilado por LaTeX).
Respuesta1
En biblatex
, el formato de campo como corchetes, énfasis o cursiva no se debe escribir directamente en la macro en la mayoría de los casos, se debe lograr con \DeclareFieldFormat
. De esa manera, se asegurará de que biblatex
pueda detectar correctamente los campos vacíos y no hacer nada en ese caso.
Podrías simplemente hacer
\DeclareFieldFormat{country}{\mkbibparens{#1}}
\DeclareCiteCommand{\citecountry}
{\boolfalse{citetracker}%
\boolfalse{pagetracker}%
\usebibmacro{prenote}}
{\printfield{country}}
{\multicitedelim}
{\usebibmacro{postnote}}
Luego, el campo se incluye entre corchetes cada vez que se muestra y, en caso contrario, se ignora. Tenga en cuenta que no es necesario envolver un single \printfield
en un \printtext
argumento sin argumento; \printfield{country}
hará lo mismo que \printtext{\printfield{country}}
.
En lugar de definirlo \citecontrib
como lo hace ahora, probablemente debería definir un controlador de bibliografía @contribution
así (esto es solo un primer intento, pero ya entiende la 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}}
Entonces puedes usarlo \fullcite
y listo.
Respuesta2
Debe verificar si el campo existe como parte del \DeclareCiteCommand
uso\iffieldundef
(o algo similar; consulte la sección4.6.2 Pruebas independientesen elbiblatex
documentación):
\DeclareCiteCommand{\citecountry}
{\boolfalse{citetracker}%
\boolfalse{pagetracker}%
\usebibmacro{prenote}}
{\iffieldundef{country}{}{(\printtext{\printfield{country}})}}
{\multicitedelim}
{\usebibmacro{postnote}}
y aquí está \printcontrib
:
\newcommand{\printcontrib}[1]{%
\citeauthor*{#1},
\citetitle*{#1},
\citeevent{#1},
\citecity{#1}
\citecountry{#1},
\citedate{#1} (\citeyear{#1})
}
También puedes escribir uno más grande \DeclareCiteCommand
en lugar de usar \printcontrib
.