使用 BibLaTeX 和 pgffor 时避免打印空书目的标题

使用 BibLaTeX 和 pgffor 时避免打印空书目的标题

我正在使用pgfforbiblatex生成年度书目,并将书目标题设置为年份。如何避免在下面的 MWE 中打印空书目的标题?

\documentclass{article}
\usepackage[defernumbers=true,backend=biber]{biblatex}
\usepackage{filecontents,pgffor}
\begin{filecontents}{references.bib}
    @Article{Kalman1964,
        author    = {Kalman, R. E.},
        title     = {When is a linear control system optimal?},
        journal   = {J. Basic Eng.},
        year      = {1964},
        volume    = {86},
        number    = {1},
        pages     = {51--60},
    }
    @InProceedings{Kalman1963,
        author    = {Kalman, R. E.},
        title     = {Lyapunov functions for the problem of lur'e in automatic control},
        booktitle = {Proceedings of the national academy of sciences},
        year      = {1963},
        volume    = {49},
        number    = {2},
        pages     = {201--205},
    }
    @Article{Kalman1960,
        author  = {Kalman, R. E.},
        title   = {A new approach to linear filtering and prediction problems},
        journal = {Trans. ASME J. Basic. Eng.},
        year    = {1960},
        volume  = {82D},
        pages   = {35--45},
    }
\end{filecontents}

\newcommand{\yearcheck}[1]{
    \defbibcheck{#1}{
        \iffieldint{origyear}
        {\ifnumequal{\thefield{origyear}}{#1}{}{\skipentry}}
        {\iffieldint{year}
            {\ifnumequal{\thefield{year}}{#1}{}{\skipentry}}
            {\skipentry}
        }
    }
}
\addbibresource{references.bib}

\begin{document}
    \noindent \textbf{This works as expected, the title ``Books'' is not printed.}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=inproceedings,title={Conference Papers}]
    \end{refsection}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=article,title={Journal Papers}]
    \end{refsection}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=book,title={Books}]
    \end{refsection}
    
    \noindent \textbf{This does not work as expected, the title ``1962'' is printed even though the bibliography is empty.}
    \foreach \year in {1960,1962,1963,1964} {
        \global\yearcheck{\year}
        \begin{refsection}
            \nocite{*}
            \printbibliography[check=\year,title={\year}]
        \end{refsection}
    }
\end{document}

我目前得到的是:

编译的 MWE

答案1

check如何(\defbibcheck)和type选项过滤书目有所不同。

使用(使用 、 、type也类似)可以从一开始就判断参考书目是否为空。使用 则无法做到这一点。keywordcategorysegmentbiblatexcheck

因此,一个解决方案是尝试根据书目类别进行过滤。使用一些技巧,甚至可以根据数据动态创建这些类别。

\documentclass{article}
\usepackage[backend=biber, defernumbers=true]{biblatex}

\makeatletter
\newrobustcmd*{\SoftDeclareBibliographyCategory}[1]{%
  \ifcsundef{blx@catg@#1}
    {\global\cslet{blx@catg@#1}\@empty}
    {}%
  \ifinlist{#1}{\blx@categories}
    {}
    {\listgadd{\blx@categories}{#1}}}

\newrobustcmd*{\SoftDeclareBibliographyCategoryX}[1]{%
  \begingroup
  \edef\blx@tempa{\endgroup
    \SoftDeclareBibliographyCategory{#1}}%
  \blx@tempa}
\makeatother

\newcommand*{\categoryyears}{}
\AtDataInput{%
  \SoftDeclareBibliographyCategoryX{year:\thefield{year}}%
  \xifinlist{\thefield{year}}{\categoryyears}
    {}
    {\listxadd{\categoryyears}{\thefield{year}}}%
  \addtocategory{year:\thefield{year}}{\thefield{entrykey}}}


\begin{filecontents}{\jobname.bib}
@article{Kalman1964,
  author    = {Kalman, R. E.},
  title     = {When is a linear control system optimal?},
  journal   = {J. Basic Eng.},
  year      = {1964},
  volume    = {86},
  number    = {1},
  pages     = {51--60},
}
@inproceedings{Kalman1963,
  author    = {Kalman, R. E.},
  title     = {Lyapunov functions for the problem of lur'e in automatic control},
  booktitle = {Proceedings of the national academy of sciences},
  year      = {1963},
  volume    = {49},
  number    = {2},
  pages     = {201--205},
}
@article{Kalman1960,
  author  = {Kalman, R. E.},
  title   = {A new approach to linear filtering and prediction problems},
  journal = {Trans. ASME J. Basic. Eng.},
  year    = {1960},
  volume  = {82D},
  pages   = {35--45},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
  \begin{refsection}
  \nocite{*}
  \printbibliography[type=inproceedings,title={Conference Papers}, resetnumbers]
  \printbibliography[type=article,title={Journal Papers}, resetnumbers]
  \printbibliography[type=book,title={Books}, resetnumbers]
  \end{refsection}

  \begin{refsection}
  \nocite{*}
  \def\do#1{\printbibliography[category=year:#1, title=#1, resetnumbers]}
  \dolistloop\categoryyears
  \end{refsection}
\end{document}

几种不同的参考书目列表。


由于列表中的数字不会是唯一的,因此无论如何都没有必要使用它们进行引用,因此您可以让数字由真实的数字生成,enumerate而不是尝试biblatex生成可引用的标签,从而使您的生活变得更加轻松。

\documentclass{article}
\usepackage[backend=biber, defernumbers=true]{biblatex}

\makeatletter
\newrobustcmd*{\SoftDeclareBibliographyCategory}[1]{%
  \ifcsundef{blx@catg@#1}
    {\global\cslet{blx@catg@#1}\@empty}
    {}%
  \ifinlist{#1}{\blx@categories}
    {}
    {\listgadd{\blx@categories}{#1}}}

\newrobustcmd*{\SoftDeclareBibliographyCategoryX}[1]{%
  \begingroup
  \edef\blx@tempa{\endgroup
    \SoftDeclareBibliographyCategory{#1}}%
  \blx@tempa}
\makeatother

\newcommand*{\categoryyears}{}
\AtDataInput{%
  \SoftDeclareBibliographyCategoryX{year:\thefield{year}}%
  \xifinlist{\thefield{year}}{\categoryyears}
    {}
    {\listxadd{\categoryyears}{\thefield{year}}}%
  \addtocategory{year:\thefield{year}}{\thefield{entrykey}}}

\defbibenvironment{bibliography}
  {\list
     {\theenumi}
     {\usecounter{enumi}%
      \renewcommand*{\makelabel}[1]{\hss[##1]}}}
  {\endlist}
  {\item}

\begin{filecontents}{\jobname.bib}
@article{Kalman1964,
  author    = {Kalman, R. E.},
  title     = {When is a linear control system optimal?},
  journal   = {J. Basic Eng.},
  year      = {1964},
  volume    = {86},
  number    = {1},
  pages     = {51--60},
}
@inproceedings{Kalman1963,
  author    = {Kalman, R. E.},
  title     = {Lyapunov functions for the problem of lur'e in automatic control},
  booktitle = {Proceedings of the national academy of sciences},
  year      = {1963},
  volume    = {49},
  number    = {2},
  pages     = {201--205},
}
@article{Kalman1960,
  author  = {Kalman, R. E.},
  title   = {A new approach to linear filtering and prediction problems},
  journal = {Trans. ASME J. Basic. Eng.},
  year    = {1960},
  volume  = {82D},
  pages   = {35--45},
}
\end{filecontents}
\addbibresource{\jobname.bib}

\begin{document}
  \printbibliography[type=inproceedings,title={Conference Papers}]
  \printbibliography[type=article,title={Journal Papers}]
  \printbibliography[type=book,title={Books}]


  \nocite{*}
  \def\do#1{\printbibliography[category=year:#1, title=#1]}
  \dolistloop\categoryyears
\end{document}

答案2

类似这样的事情应该会起作用……但我不确定它是否会起作用

\documentclass{article}
\usepackage[defernumbers=true,backend=biber]{biblatex}
\usepackage{filecontents,pgffor}
\begin{filecontents}{references.bib}
    @Article{Kalman1964,
        author    = {Kalman, R. E.},
        title     = {When is a linear control system optimal?},
        journal   = {J. Basic Eng.},
        year      = {1964},
        volume    = {86},
        number    = {1},
        pages     = {51--60},
    }
    @InProceedings{Kalman1963,
        author    = {Kalman, R. E.},
        title     = {Lyapunov functions for the problem of lur'e in automatic control},
        booktitle = {Proceedings of the national academy of sciences},
        year      = {1963},
        volume    = {49},
        number    = {2},
        pages     = {201--205},
    }
    @Article{Kalman1960,
        author  = {Kalman, R. E.},
        title   = {A new approach to linear filtering and prediction problems},
        journal = {Trans. ASME J. Basic. Eng.},
        year    = {1960},
        volume  = {82D},
        pages   = {35--45},
    }
\end{filecontents}
\newsavebox\myBibBox
\newsavebox\myBibBoxB
\newcommand{\yearcheck}[1]{
    \defbibcheck{#1}{
        \iffieldint{origyear}
        {\ifnumequal{\thefield{origyear}}{#1}{}{\skipentry}}
        {\iffieldint{year}
            {\ifnumequal{\thefield{year}}{#1}{}{\skipentry}}
            {\skipentry}
        }
    }
}
\addbibresource{references.bib}

\begin{document}
    \noindent \textbf{This works as expected, the title ``Books'' is not printed.}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=inproceedings,title={Conference Papers}]
    \end{refsection}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=article,title={Journal Papers}]
    \end{refsection}
    \begin{refsection}
        \nocite{*}
        \printbibliography[type=book,title={Books}]
    \end{refsection}
    \noindent \textbf{This does not work as expected, the title ``1962'' is printed even though the bibliography is empty.}
    \foreach \year in {1960,...,1964}{
        \global\yearcheck{\year}
        \begin{refsection}
            \nocite{*}
            \global\sbox\myBibBox{\vbox{\printbibliography[check=\year,heading=none]}}
            \ifdim\ht\myBibBox>\baselineskip
            \printbibliography[check=\year,title=\year]
            \fi
        \end{refsection}
    }
\end{document}

在此处输入图片描述

相关内容