# Use custom field and count elements of lists in references using biblatex/biber

I have a primary source and analyzed its references (on which pages are the references cited, like a manual backref job). I created a new library for this (like the author would to if he had LaTeX a few centuries ago) and added a custom field citedonpages with the manually discovered pages.

I would like to print this analyzed data (e.g. for displaying it in a table). Is it possible to use biblatex/biber to process additional fields (in this case citedonpages as described in citedonpages.dbx) to

• print this list for each entry
• and count the comma separated entries?

I tried to follow https://tex.stackexchange.com/a/163396/4419 but the command \printfield{citedonpages} did non work.

How can I access (print) the citedonpages field and how can I count the entries of the comma-separated values? As the real library has many entries, an automated solution would be very helpful (and ideally completely within LaTeX).

MWE (as a follow-up question of Create table from references with custom fields as columns using biblatex/biber):

\documentclass{scrbook}

\begin{filecontents*}{citedonpages.dbx}
\ProvidesFile{citedonpages.dbx}[2021/07/27 add citedonpages field to biblatex data model]
\DeclareDatamodelFields[type=field,datatype=literal]{citedonpages} %comma seperated list of values
\DeclareDatamodelEntryfields{citedonpages}
\end{filecontents*}

\begin{filecontents*}{Analysis.bib}
@Book{Miller1832a,
author    = {John Miller},
title     = {Elementary book},
year      = {1832},
citedonpages = {67,68,97},
}

@InBook{Smith1744a,
author    = {Daniel Smith},
booktitle = {Collection of important articles},
location  = {Amsterdam},
title     = {Noteworthy Article},
year      = {1744},
citedonpages = {5, 23, 37, 79, 248, 249, 254},
}
\end{filecontents*}

\usepackage{longtable,array}
\usepackage{booktabs,lipsum,tabularx}
\usepackage[backend=biber,datamodel=citedonpages,style=authortitle]{biblatex}
\usepackage{biblatex-ext-tabular}

\DeclareFieldFormat{citedonpages}{\bibstring{citedonpages}\space #1}

\defbibtabular{bibtabular}
{\renewbibmacro*{bbx:dashcheck}[2]{##2}%
\begin{longtable}{@{}llccl@{}}
\toprule
\textbf{Author} & \textbf{Title} & \textbf{Year} & \textbf{\# Citations} & \dots\ on pages\\
\midrule}
{\bottomrule
\end{longtable}}
{\anchorlang{\usebibmacro{author/editor+others}}
& \plainlang{\usebibmacro{title}}
& \plainlang{\printdate}
& 0 % how to display counter
& \printfield{citedonpages}
\\}

\begin{document}

\begin{refsection}[Analysis.bib]
\nocite{*}
\end{refsection}

\textbf{Ideally, it should output something like:}\\
Miller, John. \textit{Elementary book}. 1832. (cited 3 times on pages 67, 68, 97)\\
Smith, Daniel. “Noteworthy Article”. In: \textit{Collection of important articles}. Amsterdam,
1744. (cited 7 times on pages 5, 23, 37, 79, 248, 249, 254)

\begin{tabularx}{0.95\textwidth}{llccX}
\toprule
{\bfseries Author} & {\bfseries Title}  & {\bfseries Year} & {\bfseries \#  Citations}  & ... on pages \\\midrule%\otoprule
Miller, John       & Elementary book    & 1832             & 3 & 67, 68, 97\\
Smith, Daniel      & "Noteworthy article" & 1744           & 7 & 5, 23, 37, 79, 248, 249, 254 \\
\bottomrule
\end{tabularx}

\vspace{1cm}\textbf{Version with table} (autogenerated, but entries are missing):

\begin{refsection}[Analysis.bib]
\nocite{*}
\end{refsection}

\end{document}


We can use expl3 code to read the list of pages, remove duplicate numbers and count the number of pages.

This can be done in \DeclareFieldInputHandler, so happens right when the field citedonpages is read from the .bbl file. From the on, citedonpages contains a nicely formatted list of pages (without duplication).

The remaining code can be taken almost verbose from Create table from references with custom fields as columns using biblatex/biber, we just need to print our citedonpages field instead of the biblatex pageref list.

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}

\begin{filecontents*}{citedonpages.dbx}
\ProvidesFile{citedonpages.dbx}[2021/07/27 add citedonpages field to biblatex data model]
\DeclareDatamodelFields[type=field, datatype=literal]{citedonpages}
\DeclareDatamodelEntryfields{citedonpages}
\end{filecontents*}

\usepackage[backend=biber, style=authoryear, datamodel=citedonpages]{biblatex}
\usepackage{biblatex-ext-tabular}

\makeatletter
\ExplSyntaxOn
\clist_new:N \l__kromuchiblx_citedonpages_clist

\DeclareFieldInputHandler{citedonpages}
{
\clist_set:Nn \l__kromuchiblx_citedonpages_clist {#1}
% remove duplicates, if you want the duplicates counted,
% move this line *after* the citecount definition
\clist_remove_duplicates:N \l__kromuchiblx_citedonpages_clist
% writing a new field *while* we are processing another
% is a bit risky, ...
\blx@bbl@fieldedef{citecount}{\clist_count:N \l__kromuchiblx_citedonpages_clist}
% ... but works if we make sure *we* write \NewValue
\edef\NewValue{\clist_use:Nn \l__kromuchiblx_citedonpages_clist {,~}}
}
\ExplSyntaxOff
\makeatother

\usepackage{longtable}
\usepackage{array}
\usepackage{booktabs}

\newcolumntype{L}[1]{%
>{\raggedright\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}
\newcolumntype{C}[1]{%
>{\centering\let\newline\\\arraybackslash\hspace{0pt}}p{#1}}

\newbibmacro*{tablepageref}{%
\printfield{citedonpages}}

\renewbibmacro*{pageref}{}

\defbibtabular{bibtabular}
{\renewbibmacro*{bbx:dashcheck}[2]{##2}%
\renewbibmacro*{labeltitle}{}%
\setlength{\LTpre}{0pt}%
\setlength{\LTpost}{0pt}%
\renewcommand*{\arraystretch}{2}%
\begin{longtable}{%
@{}
L{\dimexpr0.2\textwidth-1\tabcolsep\relax}
L{\dimexpr0.25\textwidth-2\tabcolsep\relax}
L{\dimexpr0.12\textwidth-2\tabcolsep\relax}
L{\dimexpr0.22\textwidth-2\tabcolsep\relax}
L{\dimexpr0.21\textwidth-1\tabcolsep\relax}
@{}}
\toprule
\textbf{Author} & \textbf{Title} & \textbf{Year} & \textbf{\# Citations} & \dots\ on pages\\
\midrule}
{\bottomrule
\end{longtable}}
{\anchorlang{\usebibmacro{author/editor+others}}
& \plainlang{\usebibmacro{title}}
& \plainlang{\printdate}
& \plainlang{\printfield{citecount}}
& \plainlang{\usebibmacro{tablepageref}} \\}

\begin{filecontents*}{\jobname.bib}
@Book{Miller1832a,
author       = {John Miller},
title        = {Elementary book},
year         = {1832},
citedonpages = {67,67,68,97,67},
}
@inbook{Smith1744a,
author       = {Daniel Smith},
booktitle    = {Collection of important articles},
location     = {Amsterdam},
title        = {Noteworthy Article},
year         = {1744},
citedonpages = {5, 23, 37, 79, 248, 249, 254},
}
\end{filecontents*}

\begin{document}
\nocite{*}
\printbibtabular[title=Analysis]
\end{document}


• This is like magic... Thank you very much. Would it be possible to sort the table by number of citations? Is it possible at all? And if so can it be extended to the existing structure or would it be better to open a new question? Aug 1, 2021 at 19:38
• @kromuchi That is trickier. Sorting is done by Biber. But Biber does not have the number of citations available (the citedonpages field is only parsed on the LaTeX side). For that it would be easier to generate the counting by the same software that generates the citedonpages data. If the number of citations is available as a field in its own right, Biber can sort by it. Aug 1, 2021 at 19:42
• @kromuchi FWIW biblatex v3.17/Biber 2.17 can now sort by number of citations. See github.com/plk/biblatex/issues/1146. Feb 20, 2022 at 21:17
• How easy / hard would it be to replace consecutive pages 67, 68, 69 within the field citedonpages by a abbreviated (pageref-like) style 67--69? Feb 20, 2022 at 22:34
• @kromuchi Integer/string operations like this are always a bit painful (though of course not impossible). But given that the number of citations is now available, maybe you can do away with citedonpages completely and just use the normal backref feature? Feb 22, 2022 at 16:13