
Ich möchte alle Einträge in der BibLaTeX-Datenbank durchlaufen und \csxdef
basierend auf jedem Schlüssel eine generieren. Der Pseudocode für das, was ich wünsche, ist:
\foreach \EntryKey in \ListOfAllBibliography {%
\edef\UrlKeyValue{\citefield{\EntryKey}{url}}%
\StrBehind*{\UrlKeyValue}{//}[\UrlKeyValueExtracted]%
\IfStrEq{\UrlKeyValue}{}{}{%
\csxdef{Bib \UrlKeyValueExtracted}{\EntryKey}%
}%
}%
Für diesen speziellen Fall sollte diese Schleife äquivalent sein zu
\csxdef{Bib books.google.com/books?id=hEYuAQAAIAAJ}{knuth1984texbook}%
\csxdef{Bib books.google.com/books?id=54A3MuBzIrEC}{goossens1994latex}%
Die erwartete Leistung derMWE wenn das funktioniert ist:
Verweise:
- Eine Möglichkeit wäre, dies in Python zu tun, wie inKonvertieren der Bib-Datenbank in CSV, würde es aber lieber in LaTeX machen.
Code:
\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}
Antwort1
Von innen biblatex
können wir nie alle Einträge in der Datenbank durchlaufen .bib
. Wir können nur alle Einträge durchlaufen, die in der .bbl
Datei sind. Wenn Sie alle Einträge manuell zitiert oder verwendet haben, \nocite{*}
sollte es normalerweise keinen so großen Unterschied geben, aber wenn Sie eine erweiterte Funktion wie das Klonen von Einträgen oder CrossRef verwenden, erhalten Sie möglicherweise zusätzliche „geklonte“ Einträge, die nicht in der ursprünglichen Datenbank widergespiegelt sind.
Der beste Weg, um alle verfügbaren Einträge zu durchlaufen, ist wahrscheinlich \AtDataInput
. Dieser Hook wird immer dann ausgeführt, wenn ein Eintrag aus der .bbl
Datei gelesen wird (ganz am Ende des Einlesens). An dieser Stelle sind die Felder erweiterbar als Befehlssequenzen verfügbar \abx@field@<field name>
(Sie müssen also nicht mit \citefield
und Freunden herumspielen, die nicht erweiterbar sind und daher im Beispiel sowieso nichts taugen).
\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}
Antwort2
Du kennst mein usebib
Paket vielleicht, aber ich habe auch eine experimentelle expl3
Version davon. Deine Frage hat mich dazu veranlasst, eine Funktion hinzuzufügen, nämlich eine Sequenz, in der die Zitatschlüssel gespeichert werden.
Wie funktioniert usebib3
das? Für jeden Eintrag in der/den Bib-Datei(en), die wir laden, wird eine Eigenschaftenliste mit den Feldern des Eintrags erstellt. Dann können wir auf jedes Feld zugreifen, indem wir es aus der Eigenschaftenliste abrufen.
In Ihrem Fall können Sie eine neue Eigenschaftenliste erstellen, die die url
Felder als Schlüssel und die dazugehörigen Zitationsschlüssel als Werte enthält.
usebib3.sty
(Version 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 }
Testdatei mit Ihrer umbenannten Bib-Datei petergrill.bib
(hier nicht angezeigt)
\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}
Der \seq_map_inline:Nn
Teil füllt die eingangs erwähnte Eigenschaftenliste aus und \checkids
prüft, ob die Elemente vorhanden sind. title
In diesem Fall druckt er das Feld aus.