1

In working on improved documentation for a Biblatex style, I'd like to print nicely styled verbatim .bib entries beside the output for each, thereby juxtaposing cause and effect. This could be done by hand for each entry, but I hoped it might be easier to define a custom Biblatex citation command for typesetting .bib entries exactly as they appear in the file. A custom citation command would not only save tedium, but it would also help with automating documentation.

Unfortunately, I'm unsure how to access the literal data in a field, if this is even possible. I'd imagine Biber's already processing and parsing the data before Biblatex even sees it, and my use case is probably complicated by wanting to juxtapose unprocessed .bib data with stylized, processed Biblatex output. Here's a simplified version of what I have so far, along with the output for two entries:

\documentclass[a4paper]{article}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage{xcolor}
\usepackage[style=mla,backend=biber]{biblatex}

\usepackage{filecontents}

\begin{filecontents}{documentation.bib}
@article{Tibullus:2002ub,
    author = {Tibullus},
    date = {2002/2003},
    journal = {Chicago Review},
    number = {4},
    pages = {102--106},
    title = {How to Be Tibullus},
    translator = {Wray, David},
    volume = {48}}

@article{Evacuation:wj,
    date = {2016-07-15},
    entrysubtype = {newspaper},
    journal = {The Boston Globe},
    title = {Evacuation Order Lifted at Nice Airport},
    url = {www.bostonglobe.com/news/world/2016/07/15/evacuation-progress-nice-airport/KO4BytWK4wFUOxjEkSpKTN/story.html}}
\end{filecontents}

\addbibresource{documentation.bib}

\DeclareCiteCommand{\samplebib}[\texttt]
  {}%
  {\usebibmacro{citeindex}%
   \renewcommand*{\newunitpunct}{\addcomma\newline}%
   \renewcommand*{\multinamedelim}{\addspace{}and\addspace{}}%
   \usebibmacro{cite:mla:bib}}
  {}%
  {}

\newcommand{\entrycolor}{\color{teal}}
\newcommand{\fieldcolor}[1]{{\color{purple}#1}}
\newcommand{\fieldindent}{{\color{white} ~~~}}

\newcommand{\fieldcite}[1]{
  \iffieldundef{#1}%
    {}%
    {\printtext{\fieldindent\fieldcolor{#1} = \{\printfield[noformat]{#1}\}}}%
  \ifnameundef{#1}%
    {}%
    {\printtext{\fieldindent\fieldcolor{#1} = \{\printnames[family-given][-\value{listtotal}]{#1}\}}}%
  \iflistundef{#1}%
    {}%
    {\printtext{\fieldindent\fieldcolor{#1} = \{\printlist{#1}\}}}%
}

\makeatletter
\newbibmacro*{cite:mla:bib}{%
  {\entrycolor\printtext{@}\printfield{entrytype}}\{\printfield{entrykey}%
  \newunit%
  \fieldcite{author}%
  \newunit%
  \fieldcite{date}%
  \newunit%
  \fieldcite{day}%
  \newunit%
  \fieldcite{entrysubtype}%
  \newunit%
  \fieldcite{institution}%
  \newunit%
  \fieldcite{journaltitle}%
  \newunit%
  \fieldcite{journal}%
  \newunit%
  \fieldcite{month}%
  \newunit%
  \fieldcite{number}%
  \newunit%
  \fieldcite{options}%
  \newunit%
  \fieldcite{pages}%
  \newunit%
  \fieldcite{title}
  \newunit%
  \fieldcite{translator}
  \newunit%
  \fieldcite{url}
  \newunit%
  \fieldcite{volume}
  \newunit%
  \fieldcite{year}%
  \newline%
  \}
  }
\makeatother

\begin{document}

\begin{refsection}
\noindent\samplebib{Tibullus:2002ub}
\printbibliography[heading=none]
\end{refsection}

\begin{refsection}
\noindent\samplebib{Evacuation:wj}
\printbibliography[heading=none]
\end{refsection}

\end{document}

output of bibtex documentation

The output shows that the date entry is now gone, replaced by year, month, and day as needed, without any range. Likewise the journal field is converted with journaltitle--though this kind of conversion is less of a problem. Other entries will have similar substitutions, too, but they boil down to the same problem. (I understand why this is the default and have no complaints!) Is it possible to insist that Biblatex should show the literal .bib input for every field, or are these values out of reach? Perhaps more importantly, have I overlooked a better way to programmatically typeset Bibtex data from an existing .bib file for documentation?

12
  • I've been working on this for awhile now and had my hopes raised this morning when I saw this question: tex.stackexchange.com/questions/601342/… (Unfortunately, we weren't after the same goal.)
    – jmclawson
    Commented Jun 15, 2021 at 16:09
  • why don't you simply input the bib (or a part by line number or with some markers) with the listings package? Commented Jun 15, 2021 at 18:08
  • 2
    you could use line range markers, see 5.7 Arbitrary linerange markers in the listings docu. Commented Jun 15, 2021 at 19:26
  • 2
    It is very tricky to reconstruct the .bib data on the LaTeX side because you'd have to undo all of Biber's pre-processing steps (most prominently date parsing, but also field aliasing [journal -> journaltitle] and much more for crossref etc.) That might be possible for simple examples, but becomes less and less viable the more advanced features of biblatex you want to use.
    – moewe
    Commented Jun 15, 2021 at 21:09
  • 1
    In my last comment I should have probably made clearer that once on the LaTeX side of things you absolutely cannot distinguish whether input used journal or journaltitle (that is the point of the sourcemapping by Biber). Of course Biber would have the info available, but it's not exposed to the LaTeX side of things. For most simple dates it should be possible to reconstruct the date value, but it would get fairly messy for complex dates.
    – moewe
    Commented Jun 16, 2021 at 6:03

2 Answers 2

1

Reconstructing the bib-file from the bbl is not really possible as biber does a number of preprocessing you can't revert on the LaTeX side.

So I would use the listings package to include the bib-file verbatim.

A part of the file can be selected either by line numbers or --- if the line numbers are not stable enough --- you can use range markers as described in the listings documentation, 5.7 Arbitrary linerange markers.

1
1

Instead of preprocessing the files yourself you can also use Bibtool, which allows to extract single entries from a .bib file (among many other things).

You can call Bibtool from within LaTeX using \write18 to save an entry to a temporary file and then use \lstinputlisting on that file. Note that this requires compiling with -shell-escape.

Bibtool does some processing on the file, such as adding a newline at the startof the file, and converting cite keys to lower case. You can switch that off.

MWE, based on your gist:

\documentclass[a4paper]{article}
\usepackage[american]{babel}
\usepackage{csquotes}
\usepackage{xcolor}
\usepackage[style=mla,backend=biber]{biblatex}
\usepackage{listings}

\lstdefinelanguage{BibTeX}{%
  % keywordsprefix={@}%
  keywords={%
    @book,@article,@incollection,@suppbook,@mvbook,@collection,@review,@misc,%
    @thesis,@mvreference,@inreference,@mvlexicon,@inlexicon,@unpublished,%
    @commentary,@inbook,@incommentary,@mvcommentary,@seminarpaper,@lexicon,%
    @reference,@mvcollection,@bookinbook,@ancienttext,@classictext,@online,%
    @manual,@conferencepaper,@series%
  },
  emph={%
    author,title,location,publisher,date,shorttitle,translator,edition,preface,%
    related,relatedtype,editor,series,shortseries,number,journal,journaltitle,%
    shortjournal,volume,pages,type,booktitle,bookauthor,origlocation,%
    origpublisher,origdate,pubstate,origlanguage,maintitle,maineditor,part,%
    bookeditor,seriesseries,maintranslator,eprint,eprinttype,doi,url,%
    revdauthor,revdtitle,revdeditor,institution,type,shorthand,xref,%
    note,eprintdate,volumes,shortmaintitle,options,eprintclass,relatedoptions,%
    editortype,crossref,editora,editorb,editorc,editoratype,editorbtyle,%
    editorctype,entrysubtype,sorttitle,titleaddon,witheditor,witheditortype,%
    withtranslator,withtranslatortype,eventtitle,venue,eventdate,shortauthor%
  },
  sensitive=false,
  breaklines=true,
  %breakatwhitespace=true,
  morecomment=[l][basicstyle]{=\ \{}
}

\lstset{%
 language=BibTeX,
 backgroundcolor=\color{gray!5},
 basicstyle=\ttfamily\small,
 keywordstyle=\color{teal},
 emphstyle=\color{purple}
}

\lstset{rangeprefix=\%\[\[\ ,% percent + double left square brace + space 
        rangesuffix=\ \]\]}% space + double right square bracket 
        
\addbibresource{documentation.bib}

\newcommand{\sidebyside}[1]{%
\begin{refsection}%
\nocite{#1}%
\immediate\write18{bibtool -- suppress.initial.newline=true -- preserve.key.case=on -X "^#1$" documentation.bib -o tmpsingle.bib}%
\lstinputlisting{tmpsingle.bib}%
\printbibliography[heading=none]
\end{refsection}
}

\begin{document}
\sidebyside{Tibullus:2002ub}

\sidebyside{Evacuation:wj}
\end{document}

Result:

enter image description here

Remark: tested on Linux only, I'm not sure the command line call will work as given on Windows or Mac - but if it doesn't then probably it can be adjusted easily.

1
  • I'd seen Bibtool mentioned in some other answers to other questions, but I wasn't aware it was able to do the kinds of things you show here. This looks like a great addition to the workflow. Thank you for suggesting it!
    – jmclawson
    Commented Jun 16, 2021 at 16:10

You must log in to answer this question.

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