引用参考文献的一个奇妙特性是能够为文件中的每个条目指定一个以逗号分隔的主题列表.bib
,并且让命令(假设,\tcite{topiclist}
)自动扩展为一个等效\cite
命令,其中包含所有参考键,其主题列表与具有非空交集topiclist
。
在下面的示例中,我使用keywords
每个 BiBTeX 条目的字段来指定主题列表。因此,该命令\tcite{physics}
确定引用einstein
和hawking
包含physics
作为主题,因此扩展为\cite{einstein,hawking}
。同样,\tcite{time,space}
确定三个条目具有与集合 { time
, space
} 相交的主题列表,并扩展为以下三个条目:\cite{hawking,paine,hough}
。
平均能量损失
mybib.bib
:
@book{einstein,
author = {Einstein, Albert},
title = {The World as I See it},
keywords = {physics}
}
@book{hawking,
author = {Hawking, Stephen},
title = {A Brief History of Time},
keywords = {physics,time,space}
}
@book{paine,
author = {Paine, X. S.},
title = {A Masochist's Guide to Deciphering TeX Errors},
keywords = {tex,time}
}
@book{hough,
author = {Houghendorfer, Owain},
title = {LaTeX for Stooges: Moe Curly Braces},
keywords = {tex,space,stooges}
}
main.tex
:
\documentclass{scrartcl}
\begin{document}
% Desired code:
% Physics~\tcite{physics} deals with time/space~\tcite{time,space}.
% Equivalent code:
Physics~\cite{einstein,hawking} deals with time/space~\cite{hawking,paine,hough}.
\bibliographystyle{plain}
\bibliography{mybib}
\end{document}
是否有一个包可以做到这一点?
如果没有的话,是否有一些善良而聪明的人愿意发布它的实现?
我怀疑这样的事情pgfkeys
并非不可能,尽管我不知道读取/解析.bib
文件内容、计算字符串值列表的交集等是否可以在 LaTeX 中轻松完成。
请注意,我并不打算使用该keywords
字段。指定主题列表的方法可以是任何方式,只要它可以放在每个参考文献的 BibTeX 条目中或附近的某个位置即可。
另请注意,我愿意使用 BibLaTeX 或其他可以读取.bib
文件的替代书目包。
答案1
这里有一个expl3
实现,它使用一个prop
列表来存储包含每个唯一(区分大小写)关键字的条目,然后根据关键字列表收集条目并传递给引用命令。
首先,您需要使用 读取.bib
文件\ReadBibFile{<file-name.bib>}
,然后使用 引用条目\tcite[<command>]{<keywords>}
。默认<command>
值为\cite
。
该实施基于usebib
包:它创建@
一个活动字符,该字符将查找 bib 条目,然后使用 keyval 包来解析键。此实现用于l3keys
进行解析。下面的代码仅定义了keywords
,但您可以通过添加相应的键处理程序来扩展它以解析其他键。
\begin{filecontents*}[overwrite]{\jobname.bib}
@book{einstein,
author = {Einstein, Albert},
title = {The World as I See it},
keywords = {physics}
}
@book{hawking,
author = {Hawking, Stephen},
title = {A Brief History of Time},
keywords = {physics,time,space}
}
@book{paine,
author = {Paine, X. S.},
title = {A Masochist's Guide to Deciphering TeX Errors},
keywords = {tex,time}
}
@book{hough,
author = {Houghendorfer, Owain},
title = {LaTeX for Stooges: Moe Curly Braces},
keywords = {tex,space,stooges}
}
\end{filecontents*}
\documentclass{scrartcl}
\usepackage{xparse}
\ExplSyntaxOn
\keys_define:nn { coto }
{
, keywords .code:n = { \coto_add_keywords:n {#1} }
, unknown .code:n = { } % ignore unknown keys
}
\NewDocumentCommand \ReadBibFile { m } { \coto_read_bib:n {#1} }
\NewDocumentCommand \tcite { O{\cite} m }
{
\tl_clear:N \l__coto_tmpa_clist
\clist_map_inline:nn {#2}
{
\prop_get:NnNTF \g_coto_keywords_prop {##1} \l__coto_tmpa_tl
{ \clist_put_right:Nx \l__coto_tmpa_clist { \l__coto_tmpa_tl } }
{ \msg_error:nnn { coto } { no-entries } {#2} }
}
\clist_remove_duplicates:N \l__coto_tmpa_clist
\use:x { \exp_not:n {#1} { \exp_not:V \l__coto_tmpa_clist } }
}
% Implementation
\tl_new:N \l_coto_entry_tl
\tl_new:N \l__coto_tmpa_tl
\ior_new:N \l__coto_bib_ior
\clist_new:N \l__coto_tmpa_clist
\quark_new:N \q__coto_stop
\prop_new:N \g_coto_keywords_prop
\cs_new_protected:Npn \coto_add_keywords:n #1
{ \clist_map_function:nN {#1} \__coto_add_to_keyword:n }
\cs_new_protected:Npn \__coto_add_to_keyword:n #1
{
\prop_get:NnNTF \g_coto_keywords_prop {#1} \l__coto_tmpa_tl
{
\clist_if_in:NnF \l__coto_tmpa_tl {#1}
{
\tl_put_right:Nx \l__coto_tmpa_tl { , \l_coto_entry_tl }
\prop_gput:NnV \g_coto_keywords_prop {#1} \l__coto_tmpa_tl
}
}
{ \prop_gput:NnV \g_coto_keywords_prop {#1} \l_coto_entry_tl }
}
\prg_generate_conditional_variant:Nnn \clist_if_in:nnTF { V } { T, F, TF }
\cs_new_protected:Npn \coto_read_bib:n #1
{
\file_if_exist:nTF {#1}
{
\group_begin:
\__coto_bib_setup:
\file_input:n {#1}
\group_end:
}
{ \msg_error:nnn { coto } { file-not-found } {#1} }
}
\cs_new_protected:Npn \__coto_bib_setup:
{
\char_set_catcode_group_begin:N \{
\char_set_catcode_group_end:N \}
\char_set_catcode_other:N \%
\char_set_catcode_other:N \,
\char_set_catcode_active:N \@
\char_set_active_eq:NN \@ \__coto_read_bib_entry:w
}
\cs_new_protected:Npn \__coto_read_bib_entry:w #1
# {
\char_set_catcode_other:N \@
\__coto_read_bib_entry:n
}
\cs_new_protected:Npn \__coto_read_bib_entry:n #1
{ \__coto_read_bib_entry_aux:w #1 , \q__coto_stop }
\cs_new_protected:Npn \__coto_read_bib_entry_aux:w #1 , #2 \q__coto_stop
{
\tl_set:Nn \l_coto_entry_tl {#1}
\keys_set:nn { coto } {#2}
\char_set_catcode_active:N \@
}
\msg_new:nnn { coto } { file-not-found } { File~`#1'~not~found. }
\msg_new:nnn { coto } { no-entries } { No~entries~found~for~keyword~`#1'. }
\ExplSyntaxOff
\ReadBibFile{\jobname.bib}
\begin{document}
% Desired code:
With \verb|\tcite|: Physics~\tcite{physics} deals with time/space~\tcite{time,space}.
% Equivalent code:
With \verb| \cite|: Physics~\cite{einstein,hawking} deals with time/space~\cite{hawking,paine,hough}.
\bibliographystyle{plain}
\bibliography{\jobname}
\end{document}