Я хотел бы иметь команду, которая выдавала бы мне количество авторов заданной записи bib. То, что я безуспешно пытался сделать до сих пор, было создание хранилища ключ-значение (prop), подключение к механизму импорта bbl и сохранение количества авторов, которое должно присутствовать в счетчике авторов.
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{key,
author = {John Doe and Mike Smith},
year = {2001},
title = {Title},
publisher = {Publisher},
}
@book{key2,
author = {John Doe},
year = {2002},
title = {Title2},
publisher = {Publisher2},
}
\end{filecontents}
\usepackage{biblatex}
\addbibresource{\jobname.bib}
\usepackage{expl3}
\ExplSyntaxOn
\prop_new:N \g_my_author_count
\cs_new_protected:Npn \storecount#1#2{%
\prop_gput:Nnn \g_my_author_count{#1}{#2}%
}
\cs_new:Npn \getcount#1{%
\prop_item:Nn \g_my_author_count{#1}%
}
\ExplSyntaxOff
\newcounter{authorcount}
\setcounter{authorcount}{0}
\AtDataInput{%
\storecount{\strfield{entrykey}}{\value{author}}%
% debug stuff begin
\storecount{fakekey}{123}%
\addtocounter{authorcount}{\value{author}}%
\global\edef\entrykey{\strfield{entrykey}}%
% debug stuff end
}
% make sure it's defined
\makeatletter
\@ifundefined{entrykey}{\edef\entrykey{\empty}}{}
\makeatother
\begin{document}
% debug stuff begin
% expect 3
\arabic{authorcount} % got 3 => hook & counter work
% expect key or key2
\entrykey % got key => \strfield{entrykey} works
% expect [?] - 123
[?] - \getcount{fakekey} % got [?] - 123
% => storage works
% debug stuff end
% expect [2] - 2
\cite{key} - \getcount{key} % got [2] -
% expect [1] - 1
\cite{key2} - \getcount{key2} % got [1] -
\printbibliography
\end{document}
Что я упускаю?
решение1
Поскольку информация присутствует в author
счетчике, когда запись обрабатывается, номер может быть извлечен напрямую с помощью \cite...
команды -like. Обходной путь не \AtDataInput
требуется.
Поскольку команды biblatex
's \cite
надежны, это не возвращает вам количество авторов в расширяемом виде. Если это необходимо, может быть, действительно, проще пройти \AtDataInput
или позволить \cite
команде like сохранить соответствующий счетчик во вспомогательном макросе. Что будет более разумным, будет зависеть от варианта использования.
\documentclass{article}
\usepackage{biblatex}
\addbibresource{biblatex-examples.bib}
\DeclareCiteCommand{\citeauthorcount}
{\boolfalse{citetracker}%
\boolfalse{pagetracker}%
\usebibmacro{prenote}}
{\printtext{The entry}%
\setunit{\addspace}%
\printfield{entrykey}%
\setunit{\addspace}%
\printtext{has \arabic{author} author(s)}}
{\multicitedelim}
{\usebibmacro{postnote}}
\begin{document}
\citeauthorcount{sigfridsson,worman}
\printbibliography
\end{document}
У записи sigfridsson 2 автора(ов), У записи worman 1 автор(ов)
Если я правильно понимаю, основная проблема с вашим expl3
решением заключалась в расширении и отсутствии \the
. MWE использовал n
аргументы -type и поэтому не сохранял значения счетчика, а скорее его внутреннее представление и аналогично для \strfield{entrykey}
: n
Версия просто сохраняла бы \strfield{entrykey}
, но x
версия расширяет это и поэтому записывает sigfridsson
и worman
. Следующая реализация должна работать.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{biblatex}
\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\prop_new:N \g_vh_author_count
\cs_new_protected:Npn \vh_store_author_count:nn #1#2
{
\prop_gput:Nnn \g_vh_author_count {#1} {#2}
}
\cs_generate_variant:Nn \vh_store_author_count:nn {xx}
\cs_new:Npn \vh_get_author_count:n #1
{
\prop_item:Nn \g_vh_author_count {#1}
}
\NewExpandableDocumentCommand \getauthorcount {m} {
\vh_get_author_count:n { #1 }
}
\AtDataInput{%
\vh_store_author_count:xx {\strfield{entrykey}}{\the\value{author}}%
}
\ExplSyntaxOff
\addbibresource{biblatex-examples.bib}
\begin{document}
\cite{sigfridsson} - \getauthorcount{sigfridsson}
\cite{worman} - \getauthorcount{worman}
\edef\foo{\getauthorcount{worman}} \meaning\foo
\edef\foo{\getauthorcount{sigfridsson}} \meaning\foo
\printbibliography
\end{document}
[1] - 2
[2] - 1
макрос:->1
макрос:->2