2

I am updating a list of references and I would like to highlight references added since the last update. For example, I would like to add an asterisk (or another symbol) just before the reference (ideally in the left margin or, at least at the beginning of the reference).

However, contrary to numerous questions already asked (e.g. asterisk added following some keywords), I would like to add the asterisk automatically according to a specific date.

The .bib file was created with JabRef, so each reference have a field "timestamp" (format: yyyy-mm-dd or yyyy.mm.dd). This field could be used for add the asterisk.

The MWE:

\documentclass{article}
\usepackage[style=authoryear,backend=biber]{biblatex}
\usepackage{filecontents}

\begin{filecontents}{\jobname.bib}
@book{Rabelais1532,
  author = {Rabelais, Fran\c{c}ois},
  date = {1532},
  title = {Pantagruel},
  timestamp = {2018-07-01},
}
@book{Hugo1862,
  author = {Hugo, Victor},
  date = {1862},
  title = {Les Mis\'{e}rables},
  timestamp = {2019-07-01},
}
@book{Hugo1831,
  author = {Hugo, Victor},
  date = {1831},
  title = {Notre-Dame de Paris},
  timestamp = {2020.01.31},
}
@book{Zola1885,
  author = {Zola, \'{E}mile},
  date = {1885},
  title = {Germinal},
  timestamp = {2020-02-01},
}
@book{Balzac1831,
  author = {de Balzac, Honor\'{e}},
  date = {1831},
  title = {The Skin of Sorrow},
  timestamp = {2020-06-15},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

I have tried to adapt the following piece of code given in this post, without success:

\renewbibmacro*{begentry}{%
    \iftimestamp{<thechoosendate>}{%
        \makebox[0pt][r]{\textasteriskcentered\addspace}%
    }{}%
}

For example, I would like highlight references added since 31st January 2020 (timestamp>=2020-01-31).

Maybe we can use the package datetime2 and the commands \DTMsavedate{lastupdatedate}{2020-01-31} and \DTMusedate{lastupdatedate} to optimize the upcoming updates.

  1. How can I do to obtain all recent references identified by an asterisk?
  2. What document should be read to learn how to make this type of programmation?

1 Answer 1

2

I imagine there are a great many ways to deal with this.

The first step in any case would be to make sure the timestamp data gets to Biber. In the standard data model there is no such field as timestamp, so the field is simply ignored. There are at least two straightforwaed ways to get the timestamp data to biblatex:

  1. Declare a new data model with the timestamp field.
  2. Remap timestamp to a known field (for example the scratch field 'usera').

In what follows below we will use a combination of the two approaches. We will declare a new date field timestampdate and will map timestamp that field with a Biber sourcemap (for technical reasons all date fields in biblatex must end with ...date, so timestampdate seemed like a good choice). I chose this more complicated route, because we can then have Biber parse the field as a date and return year, month and day separately. Furthermore, we can use this step to normalise the date formats from YYYY.MM.DD to YYYY-MM-DD.

It would be perfectly possible to pass timestamp through as is and not via a ...date field, but then you would have to parse the date on the LaTeX side (which shouldn't be too tricky).

With the date passed through to biblatex we just need to check if we are no older than a given date. That can simply be checked by going through the date parts year, month and day one by one. For our date field timestampdate the year will live in timestampyear, the month in timestampmonth etc. We can access the raw fields with \thefield.

\documentclass{article}

\begin{filecontents}{timestampdate.dbx}
\ProvidesFile{timestampdate.dbx}[2020/08/19 timestampdate for biblatex]
\DeclareDatamodelFields[type=field, datatype=date, skipout]{
  timestampdate,
}
\DeclareDatamodelEntryfields{
  timestampday,
  timestampendday,
  timestampendhour,
  timestampendminute,
  timestampendmonth,
  timestampendsecond,
  timestampendtimezone,
  timestampendyear,
  timestamphour,
  timestampminute,
  timestampmonth,
  timestampsecond,
  timestamptimezone,
  timestampyear,
}
\end{filecontents}

\usepackage[style=authoryear, backend=biber, datamodel=timestampdate]{biblatex}

\DeclareSourcemap{
  \maps{
    \map{
      % map timestamp to date field timestampdate
      \step[fieldsource=timestamp, fieldtarget=timestampdate]
      % now convert '.' to '-'
      \step[fieldsource=timestampdate, match=\regexp{\.}, replace=\regexp{-}]
      % we should now have YYYY-MM-DD format
    }
  }
}

\makeatletter
% {<datetype prefix>}{<year>}{<month>}{<day>}
% checks if the date stored in the field <datetype>
% is at least <year>-<month>-<day>
% ---
% to understand the code below just 'map'
% \@firstoftwo  -> true
% \@secondoftwo -> false
\newcommand*{\ifdateatleast}[4]{%
  \ifnumgreater{\thefield{#1year}}{#2}
    {\@firstoftwo}
    {\ifnumequal{\thefield{#1year}}{#2}
       {\ifnumgreater{\thefield{#1month}}{#3}
          {\@firstoftwo}
          {\ifnumequal{\thefield{#1month}}{#3}
             {\ifnumless{\thefield{#1day}}{#4}
                {\@secondoftwo}
                {\@firstoftwo}}
             {\@secondoftwo}}}
       {\@secondoftwo}}%
}
\makeatother

\renewbibmacro*{begentry}{%
  \ifdateatleast{timestamp}{2020}{1}{1}
    {\makebox[0pt][r]{\textasteriskcentered\addspace}}
    {}%
}

\begin{filecontents}{\jobname.bib}
@book{Rabelais1532,
  author    = {Rabelais, Fran\c{c}ois},
  date      = {1532},
  title     = {Pantagruel},
  timestamp = {2018-07-01},
}
@book{Hugo1862,
  author    = {Hugo, Victor},
  date      = {1862},
  title     = {Les Mis\'{e}rables},
  timestamp = {2019-07-01},
}
@book{Hugo1831,
  author    = {Hugo, Victor},
  date      = {1831},
  title     = {Notre-Dame de Paris},
  timestamp = {2020.01.31},
}
@book{Zola1885,
  author    = {Zola, \'{E}mile},
  date      = {1885},
  title     = {Germinal},
  timestamp = {2020-02-01},
}
@book{Balzac1831,
  author    = {de Balzac, Honor\'{e}},
  date      = {1831},
  title     = {The Skin of Sorrow},
  timestamp = {2020-06-15},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
\nocite{*}
\printbibliography
\end{document}

Some entries are highlighted.

To be honest, I'm not sure where you would start reading up on programming this. The most important point here is getting the data to biblatex, because timestamp is ignored by default (Add field "tome" to biblatex entries shows some methods to get a 'new' field to biblatex). After that you 'just' need to make sure to parse the date and compare it. There are multiple ways to do that. I just happened to choose one that involves Biber and biblatex date handling, but this is not a given. You could also parse everything yourself (cf. Is it possible to parse a date string in LaTeX to convert it to a different date format?).

You must log in to answer this question.

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