我希望能够指定一个列表,用于创建类别并向其中添加条目。
我使用 pgffor 来以方便的方式指定类别名称和标题。我在此示例中使用的类别是任意的,但字段值和类别的一般使用则不是。
平均能量损失
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[defernumbers=true,sorting=ydnt,doi=false,eprint=false,isbn=false]{biblatex}
\renewcommand*{\bibfont}{\footnotesize}
\usepackage{pgffor}
\xdef\bibcats{}
\newcommand*{\addcat}[2]{%
\DeclareBibliographyCategory{#1}%
\defbibheading{#1}{\subsection*{#2}}%
}
\foreach \catg/\head in {phdthesis/PhD. Thesis,article/Articles}{%
\edef\tmp{\noexpand\addcat{\catg}{\head}}
\tmp
\listxadd{\bibcats}{\catg}
}
\addbibresource{biblatex-examples.bib}
\AtDataInput{%
\ifboolexpr{%
not test {\iffieldundef{type}}
and
test {\xifinlist{\thefield{type}}{\bibcats}}
}
{\addtocategory{\strfield{type}}{\strfield{entrykey}}}%
{\ifboolexpr{%
test {\ifnumgreater{\thefield{year}}{2000}}
and
test {\xifinlist{\thefield{entrytype}}{\bibcats}}
}%
{\addtocategory{\strfield{entrytype}}{\strfield{entrykey}}}%
{}%
}%
}
\begin{document}
\nocite{*}
\printbibheading
\bibbycategory
\end{document}
结果
除了设置标题外,上述操作均有效,并会引发错误,Package biblatex Error: Heading <phdthesis/article> could not be found.
导致:
期望结果
我希望通过将 foreach 循环替换为
\addcat{phdthesis}{PhD. Thesis}
\addcat{article}{Articles}
\forcsvlist{\listxadd\bibcats}{phdthesis,article}
给予
问题
我希望类别的创建依赖于列表。鉴于非 foreach 循环方法有效,我怀疑问题主要来自扩展问题。
- 如何根据列表创建类别和相应的标题?
- 为什么我尝试过的处理扩展的方法不起作用?
答案1
我认为问题在于您\defbibheading
正在一个组中执行,因此在那里定义的命令(用\newcommand
)在您需要时不可用。
从 egreg 的答案中窃取全局 renewcommand 的代码定义这样的命令,我们重新定义了 biblatex 的内部工作原理,\defbibheading
以利用这种全局重新定义:
\makeatletter
\def\gnewcommand{\g@star@or@long\gnew@command}
\def\grenewcommand{\g@star@or@long\grenew@command}
\def\g@star@or@long#1{%
\@ifstar{\let\l@ngrel@x\global#1}{\def\l@ngrel@x{\long\global}#1}}
\def\gnew@command#1{\@testopt{\@gnewcommand#1}0}
\def\@gnewcommand#1[#2]{%
\kernel@ifnextchar [{\@gxargdef#1[#2]}%
{\@argdef#1[#2]}}
\let\@gxargdef\@xargdef
\patchcmd{\@gxargdef}{\def}{\gdef}{}{}
\let\grenew@command\renew@command
\patchcmd{\grenew@command}{\new@command}{\gnew@command}{}{}
\def\blx@defbibheading#1[#2]{%
\csundef{#1}%
\expandafter\gnewcommand\csname#1\endcsname[1][#2]}
\makeatother
现在一切都按预期工作了。我不知道是否有其他方法可以避免循环在组内执行并隐藏重新定义。