8

I'm using biblatex and biber for referencing works beeing showed in an history lesson. Datation in centuries (12th century or 12e siècle in french) are quite common. I used to write such dates in the field "Year", and it worked since the last upgrade:

Folowing MWE compiles with TexLive 2015…

\documentclass{article}
\usepackage{biblatex}
\usepackage[utf8]{inputenc}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
    @Thesis{exemple_image,
    Title                    = {Title of the work},
    Author                   = {Artist Name},
    Location                 = {Switzerland},
    Year                     = {{\siecle{15}}},
    }
\end{filecontents}
\addbibresource{\jobname.bib}

\newcommand{\siecle}[1]{%
\textsc{\romannumeral #1}\textsuperscript{e}~siècle
}

\nocite{*}

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

reference correctly printed

…but not anymore with TexLive 2016, where I've got an error: ! Use of /sortlist doesn't match its definition.

I guess Biblatex 3.5 is less permissive with the "Year" field. I've searched in the documentation without success and I'm open to all suggestions.

  • If you're not sorting by date, then the easiest thing to do is to use another field, such as addendum. – jon Jan 20 '17 at 17:25
  • Thank you, yes I could do it, but if I have to change all my .bib files, I would prefer too have another solution, like writing 15uu in the "date" field and change some biblatex commands to print it the right way. – omisson Jan 20 '17 at 18:15
5

With the new ISO 8601 date features of biblatex 3.10 and above you can input a century as

date = {19XX}

Unfortunately, the standard date formats do not deal with this out of the box by showing '20th century' or similar output, they'd just write '1900-1999', but we can enable handling of centuries as follows

\documentclass[french]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{csquotes}
\usepackage{biblatex}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@thesis{exemple_image,
  title    = {Title of the work},
  author   = {Artist Name},
  location = {Switzerland},
  date     = {16XX},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\NewBibliographyString{century}
\DefineBibliographyStrings{french}{century = {siècle}}

\makeatletter
\renewcommand*{\RNfont}{\textsc}
\DeclareFieldFormat{datecentury}{\RN{#1}\textsuperscript{e}}
\renewrobustcmd*{\mkdaterangetrunc}[2]{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {}
      {\printtext[#2date]{%
         \datecircaprint
         % Such a season component can only come from an EDTF 5.1.5 season which replaces
         % a normal month so if it exists, we know that a normal date print is ruled out
         \iffieldequalstr{dateunspecified}{yearincentury}
           {\printtext[datecentury]{\number\numexpr\thefield{#2year}/100+1\relax}\setunit{\addnbspace}\bibstring{century}}
           {\iffieldundef{#2season}
              {\iffieldsequal{#2year}{#2endyear}
                 {\iffieldsequal{#2month}{#2endmonth}
                    {\csuse{mkbibdate#1}{}{}{#2day}}
                    {\csuse{mkbibdate#1}{}{#2month}{#2day}}}
                 {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                  \iffieldsequal{#2dateera}{#2enddateera}{}
                   {\dateeraprint{#2year}}}}
              {\iffieldsequal{#2year}{#2endyear}
                {\csuse{mkbibseasondate#1}{}{#2season}}
                {\csuse{mkbibseasondate#1}{#2year}{#2season}%
                 \iffieldsequal{#2dateera}{#2enddateera}{}
                   {\dateeraprint{#2year}}}}%
            \dateuncertainprint
            \iffieldundef{#2endyear}
              {}
              {\iffieldequalstr{#2endyear}{}
                 {\mbox{\bibdaterangesep}}
                 {\bibdaterangesep
                  \enddatecircaprint
                  \iffieldundef{#2season}
                    {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}
                    {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
                  \enddateuncertainprint
                  \dateeraprint{#2endyear}}}}}}%
  \endgroup}
\makeatother

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

Where \iffieldequalstr{dateunspecified}{yearincentury} checks for a century, the format datecentury controls the output of the century and the bibstring century can be used to localise the output further.

example output

Refer also to 96-dates.tex as well as §2.3.8 Date and Time Specifications, §4.2.4.1 Generic Fields of the biblatex documentation.

  • Thx a lot, I've made a \renewbibmacro*{date}… from your answer and it works perfectly. I'm now cleaning my .bib files adopting the EDTF norm. The more I understand biblatex the more I enjoy it! – omisson Jan 21 '17 at 15:10
  • @omisson Glad to hear that it works for you. The solution should work more or less out of the box, I don't see why you should have to \renewbibmacro*{date}, did the redefinition of \mkdaterangetrunc not work for you? – moewe Jan 21 '17 at 15:27
  • It works out of the box. It's just I'm writing a cls and I prefere not to write code I don't understand. I don't know what mkdaterangetrunc is doing. It's not in the documentation. Are there some reason not to redefine the bibmacro? (I'm already doing it to print origdate). – omisson Jan 21 '17 at 15:58
  • @omisson \mkdaterangetrunc is some intermediate macro and that change would then work for most dates, not only those printed by \usebibmacro{date}. – moewe Jan 21 '17 at 16:02
  • Since biblatex 3.11, date = {19XX} should be used, perhaps could you update your answere. – omisson May 10 '18 at 11:47
7

Just change the way you define \siecle:

\newrobustcmd{\siecle}[1]{%
  \textsc{\romannumeral #1}\textsuperscript{e}~siècle
}

In such a way the macro is not expanded prematurely. Of course, the warning

WARN - year field '{\siecle{15}}' in entry 'exemple_image' is not an integer - this will probably not sort properly.

will show nonetheless.

enter image description here

  • Thx it works perfectly and I can now upgrade to TexLive 2016. Biblatex 3.5 has some surprises, but a lot of possibilities, I'm reading the documentation about dates. – omisson Jan 21 '17 at 9:14
  • With sortyear = {1600} the warning should disappear, because sortyear is the considered for sorting, but I think there was a bug with that that is only resolved in the upcoming version 2.8 of Biber. – moewe Jan 21 '17 at 12:54
  • This solution is still very useful, for special dates like "first quarter of the 12th Century" for example. I'd like to vote for both! – omisson Jan 21 '17 at 20:31
3

Another way is to rely on Biber to map the year field to another field. (This example uses addendum.) It is unclear from the example as to whether you want or need to limit the sourcemapping to a specific sub-set of entries, but there are a number of ways to do this. (This example limits to the specific .bib file and the entrytype thesis, just as an example.)

Biber will finish without warnings or errors.

\documentclass{article}
\usepackage[utf8]{inputenc}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
    @Thesis{exemple_image,
    Title                    = {Title of the work},
    Author                   = {Artist Name},
    Location                 = {Switzerland},
    Year                     = {{\siecle{15}}},
    }
\end{filecontents}
\usepackage[backend=biber]{biblatex}
\addbibresource{\jobname.bib}

\newcommand{\siecle}[1]{%
  \textsc{\romannumeral #1}\textsuperscript{e}~siècle
}

\DeclareSourcemap{
  \maps[datatype=bibtex, overwrite]{
    \map{
      \perdatasource{\jobname.bib}% <-- If you have them in a special bib file
      \pertype{thesis}%             <-- If you want to limit by type
      \step[fieldsource=year]
      \step[fieldset=addendum, origfieldval]
      \step[fieldset=year, null]
    }
  }
}

\nocite{*}

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.