
Gostaria de percorrer todas as entradas no banco de dados BibLaTeX e gerar um \csxdef
com base em cada chave. O pseudocódigo para o que desejo é:
\foreach \EntryKey in \ListOfAllBibliography {%
\edef\UrlKeyValue{\citefield{\EntryKey}{url}}%
\StrBehind*{\UrlKeyValue}{//}[\UrlKeyValueExtracted]%
\IfStrEq{\UrlKeyValue}{}{}{%
\csxdef{Bib \UrlKeyValueExtracted}{\EntryKey}%
}%
}%
Para este caso específico, este loop deve ser equivalente a
\csxdef{Bib books.google.com/books?id=hEYuAQAAIAAJ}{knuth1984texbook}%
\csxdef{Bib books.google.com/books?id=54A3MuBzIrEC}{goossens1994latex}%
O resultado esperado doMWE quando isso funciona é:
Referências:
- Uma opção seria fazer isso em python conformeConvertendo banco de dados bib em csv, mas preferiria fazer isso em LaTeX.
Código:
\begin{filecontents}{mybib.bib}
@book{knuth1984texbook,
title={The texbook},
author={Knuth, D.E. and Knuth, A.D. and Bibby, D. and American Mathematical Society and Addison-Wesley Publishing Company and Addison-Wesley},
isbn={9780201134483},
lccn={85030845},
series={Computers \& typesetting},
url={https://books.google.com/books?id=hEYuAQAAIAAJ},
year={1984},
publisher={Addison-Wesley},
myFieldA={Useful Book},
myFieldB={on Shelf 4},
}
@book{goossens1994latex,
title={The LaTeX Companion},
author={Goossens, M. and Mittelbach, F. and Samarin, A.},
isbn={9780201541991},
lccn={lc93023150},
series={Addison-Wesley series on tools and techniques for computer typesetting},
url={https://books.google.com/books?id=54A3MuBzIrEC},
year={1994},
publisher={Addison-Wesley},
myFieldA={Also Useful Book},
myFieldB={on Shelf 5},
}
\end{filecontents}
\documentclass{article}
\usepackage{xstring}% used only in pseudo code for this MWE.
\usepackage{pgffor}
\usepackage{etoolbox}
\usepackage{biblatex}
\addbibresource{mybib.bib}
\begin{document}
%% Pseudo code for desired looping:
% \foreach \EntryKey in \ListOfAllBibliography {%
% \edef\UrlKeyValue{\citefield{\EntryKey}{url}}%
% \StrBehind*{\UrlKeyValue}{//}[\UrlKeyValueExtracted]%
% \IfStrEq{\UrlKeyValue}{}{}{% Skip if the url= key us missing
% \csxdef{Bib \UrlKeyValueExtracted}{\EntryKey}%
% }%
% }%
\foreach \x in {hEYuAQAAIAAJ, 54A3MuBzIrEC} {%
\ifcsdef{Bib books.google.com/books?id=\x}{%
PASS: Found (\citefield{\csuse{Bib books.google.com/books?id=\x}}{title}).
}{%
FAIL: Missing csdef for \x.
}%
\par
}
\end{document}
Responder1
De dentro, biblatex
nunca poderemos percorrer todas as entradas do .bib
banco de dados. Só podemos fazer um loop em todas as entradas que estão no .bbl
arquivo. Se você citou manualmente todas as entradas ou usou, \nocite{*}
normalmente não deve haver muita diferença, mas se você usar algum recurso mais avançado, como clonagem de entrada ou referência cruzada, poderá acabar com entradas "clonadas" adicionais que não são refletidas no original base de dados.
A melhor maneira de percorrer todas as entradas disponíveis é provavelmente \AtDataInput
. Este gancho é executado sempre que uma entrada é lida do .bbl
arquivo (no final da leitura). Neste ponto, os campos estão disponíveis de forma expansível como sequências de comando \abx@field@<field name>
(para que você não precise mexer com \citefield
amigos que não são expansíveis e, portanto, não são bons no exemplo).
\documentclass{article}
\usepackage{xstring}
\usepackage{pgffor}
\usepackage{biblatex}
\makeatletter
\AtDataInput{%
\ifundef\abx@field@url
{}
{\edef\UrlKeyValue{\abx@field@url}%
\StrBehind*{\UrlKeyValue}{//}[\UrlKeyValueExtracted]%
\csxdef{Bib \UrlKeyValueExtracted}{\abx@field@entrykey}}}
\makeatother
\begin{filecontents}{\jobname.bib}
@book{knuth1984texbook,
title={The texbook},
author={Knuth, D.E. and Knuth, A.D. and Bibby, D.},
isbn={9780201134483},
lccn={85030845},
series={Computers \& typesetting},
url={https://books.google.com/books?id=hEYuAQAAIAAJ},
year={1984},
publisher={Addison-Wesley},
myFieldA={Useful Book},
myFieldB={on Shelf 4},
}
@book{goossens1994latex,
title={The LaTeX Companion},
author={Goossens, M. and Mittelbach, F. and Samarin, A.},
isbn={9780201541991},
lccn={lc93023150},
series={Addison-Wesley series on tools and techniques for computer typesetting},
url={https://books.google.com/books?id=54A3MuBzIrEC},
year={1994},
publisher={Addison-Wesley},
%pages={11-15},
myFieldA={Also Useful Book},
myFieldB={on Shelf 5},
}
\end{filecontents}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\foreach \x in {hEYuAQAAIAAJ, 54A3MuBzIrEC} {%
\ifcsdef{Bib books.google.com/books?id=\x}{%
PASS: Found (\citefield{\csuse{Bib books.google.com/books?id=\x}}{title}).
}{%
FAIL: Missing csdef for \x.
}%
\par
}
\end{document}
Responder2
Você pode conhecer meu usebib
pacote, mas também tenho uma expl3
versão experimental dele. Sua pergunta me levou a adicionar um recurso, ou seja, uma sequência onde as chaves de citação são armazenadas.
Como usebib3
funciona? Para cada entrada no(s) arquivo(s) bib que carregamos, ele configura uma lista de propriedades contendo os campos da entrada. Então podemos acessar cada campo recuperando-o da lista de propriedades.
No seu caso, você pode fazer uma nova lista de propriedades contendo como chaves os url
campos e como valores as chaves de citação às quais pertencem.
usebib3.sty
(versão 0.3)
\RequirePackage{expl3,xparse,url}
\ProvidesExplPackage{usebib3}{2022/05/06}{v. 0.3}{Use fields read in bib files}
\prop_new:N \l__usebib_temp_prop
\prop_new:N \g__usebib_temp_prop
\seq_new:N \g_usebib_discard_seq
\seq_new:N \g_usebib_keys_seq
\NewDocumentCommand{\bibinput}{m}
{
\clist_map_function:nN { #1 } \usebib_main:n
}
\NewExpandableDocumentCommand{\usebibentry}{mm}
{
\prop_item:cf { g_usebib_entry_#1_prop } { \str_lower_case:n { #2 } }
}
\NewExpandableDocumentCommand{\usebibentryurl}{O{|}m}
{
\__usebib_url:nf { #1 } { \prop_item:cn { g_usebib_entry_#2_prop } { url } }
}
\NewDocumentCommand{\newbibfield}{m}{}
\@ifpackageloaded{hyperref}
{
\cs_new_protected:Nn \__usebib_url:nn
{
\url{ #2 }
}
}
{
\cs_new_protected:Nn \__usebib_url:nn
{
\tl_rescan:nn { \url #1 #2 #1 }
}
}
\cs_generate_variant:Nn \__usebib_url:nn { nf }
\cs_generate_variant:Nn \prop_item:Nn { cf }
\NewDocumentCommand{\newbibignore}{m}
{
\seq_gput_right:Nx \g_usebib_discard_seq { \str_lower_case:n { #1 } }
}
\cs_new_protected:Nn \usebib_main:n
{
\group_begin:
\char_set_active_eq:NN @ \usebib_read_entry:w
\char_set_catcode_active:n { `@ }
\file_input:n { #1.bib }
\group_end:
}
\cs_new_protected:Npn \usebib_read_entry:w #1#
{
\seq_if_in:NxTF \g_usebib_discard_seq { \str_lower_case:n { #1 } }
{
\use_none:n
}
{
\__usebib_read_entry:w
}
}
\cs_new_protected:Npn \__usebib_read_entry:w
{
\group_begin:
\char_set_catcode_other:n { `@ } % may appear in text
\char_set_catcode_other:n { `\% } % can be used in URLs
\char_set_catcode_other:n { `\# } % can be used in fields
\__usebib_read_entry:n
}
\cs_new_protected:Nn \__usebib_read_entry:n
{
\prop_gset_from_keyval:Nn \g__usebib_temp_prop { USEBIBREADKEY=#1 }
\group_end:
\__usebib_save_entry:
}
\cs_new_protected:Nn \__usebib_save_entry:
{
\prop_clear:N \l__usebib_temp_prop
\prop_map_inline:Nn \g__usebib_temp_prop
{
\str_if_eq:nnTF { ##1 } { USEBIBREADKEY }
{
\seq_gput_right:Nn \g_usebib_keys_seq { ##2 }
}
{
\prop_put:Nxn \l__usebib_temp_prop { \str_lower_case:n { ##1 } } { ##2 }
}
}
\prop_new:c { g_usebib_entry_ \prop_item:Nn \g__usebib_temp_prop { USEBIBREADKEY } _prop }
\prop_gset_eq:cN
{ g_usebib_entry_ \prop_item:Nn \g__usebib_temp_prop { USEBIBREADKEY } _prop }
\l__usebib_temp_prop
}
\cs_generate_variant:Nn \prop_put:Nnn { Nx }
Arquivo de teste usando seu arquivo bib renomeado petergrill.bib
(não mostrado aqui)
\documentclass{article}
\usepackage{usebib3}
\bibinput{petergrill}
\ExplSyntaxOn
\prop_new:N \l_petergrill_url_prop
%% save the url fields
\seq_map_inline:Nn \g_usebib_keys_seq
{
\prop_put:Nxn \l_petergrill_url_prop { \usebibentry { #1 } { url } } { #1 }
}
\NewDocumentCommand{\checkids}{mm}
{% #1 = prefix, #2 = list
\clist_map_inline:nn { #2 }
{
\prop_if_in:NnTF \l_petergrill_url_prop { #1##1 }
{
PASS:~Found~(\usebibentry{\prop_item:Nn \l_petergrill_url_prop { #1##1 }}{title}) \par
}
{
FAIL:~Missing~##1
}
}
}
\ExplSyntaxOff
\begin{document}
\checkids{https://books.google.com/books?id=}{hEYuAQAAIAAJ, 54A3MuBzIrEC}
\end{document}
A \seq_map_inline:Nn
parte preenche a lista de propriedades mencionada no início e \checkids
verifica se os itens estão lá, imprimindo o title
campo neste caso.