`defbibenvironment` 中的嵌套列表

`defbibenvironment` 中的嵌套列表

我正在尝试整理一份来源列表,从内容的角度来看,这些来源是按层次分组的。具体来说就是“档案”和“档案中的收藏”。我想使用 biblatex 在我的书目/书目列表中表达这种关系。“档案”只是一个标题,“档案中的收藏”有一个简写,这是它们在文本中的引用方式。所以我在寻找一些“类似书目”的东西。

我一直在努力defbibenvironment但尚未得到满意的结果。理想情况下,我尝试为每个层次结构的源设置不同的(独立)缩进/边距/等。一种嵌套列表defbibenvironment

我能达到的最佳结果是将默认的defbibenvironment和元素混合在一起bibliography,并shorthands针对每种情况进行条件设置:

\RequirePackage{filecontents}

\begin{filecontents}{\jobname.bib}
@customa{natarch,
    title = {National Archives. But with a title long enough to span two lines. Yet a little longer.},
    sortshorthand = {NatArch},
}

@customb{natarch:presabc,
    title = {President ABC Papers. A subtitle to let it reach a second line.},
    shorthand = {NatArch -- ABC},
    sortshorthand = {NatArch -- ABC},
    xref = {natarch},
}

@customb{natarch:mintru,
    title = {Ministry of Truth Papers. Fully and continuously updated.},
    shorthand = {NatArch -- MT},
    sortshorthand = {NatArch -- MT},
    xref = {natarch},
}

@customa{libcong,
    title = {Library of Congress},
    sortshorthand = {LibCon},
}

@customb{libcong:digcoll,
    title = {Digital Collections of the Library of Congress. But with a title long enough to span two lines.},
    shorthand = {LibCon -- DC},
    sortshorthand = {LibCon -- DC},
    xref = {libcong},
}
\end{filecontents}

\documentclass{article}

\usepackage[style=authortitle,minxrefs=1]{biblatex}

\usepackage{calc}

\addbibresource{\jobname.bib}

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}

\DeclareBibliographyDriver{primary}{%
    \usebibmacro{bibindex}%
    \usebibmacro{begentry}%
    \printfield{title}%
    \usebibmacro{finentry}}

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}

\DeclareSortingTemplate{primary}{
  \sort{
    \field{sortshorthand}
  }
  \sort{
    \field{shorthand}
  }
}

\defbibenvironment{primary}
  {\list
       {}
       {\setlength{\leftmargin}{\bibhang+\biblabelsep}%
        \setlength{\itemindent}{-\leftmargin}%
        \setlength{\itemsep}{\bibitemsep}%
        \setlength{\parsep}{\bibparsep}%
        \renewcommand*{\makelabel}[1]{##1\hss}}}
  {\endlist}
  {\ifentrytype{customa}
      {\item}{}
   \ifentrytype{customb}
      {\setlength{\labelwidth}{\shorthandwidth}%
            \setlength{\labelsep}{\biblabelsep}%
            \setlength{\itemindent}{\shorthandwidth-.5\biblabelsep}%
       \item[\printfield{shorthand}]}{}
   }

\begin{document}

\nocite{libcong:digcoll,natarch:mintru,natarch:presabc}
\printbiblist[title={Primary sources}]{primary}
\printshorthands
\printbibliography

\end{document}

其结果是:

在此处输入图片描述

期望的结果是第一个“主要来源”,其他的用于比较。使用这种方法,我无法摆脱全局设置leftmargin,对于这两种类型的条目,全局设置是相同的。我只能更改它们各自的缩进。

理想情况下,我希望“档案”的行为就像参考书目中的条目(如“参考文献”),“收藏中的档案”的行为就像速记列表(如“缩写”,即左边距为shorthandwidth+biblabelsep),并带有额外的缩进以强调分组。

考虑的其他方法包括:

  • 使用 的biblatex功能related,就像multivolumerelatedtype 一样。这对我的设置有两个问题。首先,相关条目的缩进对于多行情况来说并不理想。其次,对我来说更重要的是,我需要在参考书目中为单个子条目添加钩子,以便从引文中进行链接,而我不希望它重复。

  • 使用类似 的某种机制bibbycategory。这实际上是一个好主意,将母条目作为 bibheading,并为子条目提供适当的 biblist。但是,我的来源列表更长,我不想手动填充它。此外,我不想category仅仅因为这个而限制该机制的使用(尽管我想我可能可以限制感兴趣的类别的循环)。无论如何,我无法设计出一种自动填充它的方法(DeclareSourcemap据我所知, 无法创建类别,所以我已经卡在了这一点上)。

  • 我也尝试过一些类似 Guido 的回答biblatex,biber,如何创建一个循环来逐年从 xxxx 到 yyyy 打印 bibliography?,其中涉及删除\itemfromdefbibenvironment并在 bibentry 中处理它,但我无法在这些行中找到任何可行的解决方案。

  • 我也考虑过 Philippe Goutet 的回答更改描述列表中的悬挂缩进,但这超出了我的理解范围,因此我无法真正使其适应我的目的,如果这确实可能的话。

  • 我也尝试从标准开始printbibliography,重新定义子条目的 bibdriver,尝试模拟带有mboxesparboxes和的 biblist 条目tabulars。但这种方法似乎大大扩展了 bibdriver,而 biblatex 失去了对垂直间距和标点符号的控制。虽然这些问题最终可能会得到规避,但我认为这条路线并不十分明智。

答案1

好吧,自从我问了之后,我已经找到了一个令人满意的(即使不是理想的)解决方案。我会把它作为答案发布出来,因为它可能会有用。但其他答案仍然非常受欢迎。

更新:我可以改进这个解决方案(见下面的更新),以获得非常好的结果,从输出和使用的角度来看,没有什么可挑剔的。但是,这远非易事。我会接受这个答案,因为它确实解决了 OP,但如果有人想尝试更简单的东西,我会很乐意改变这一点。

我设法安排了一个解决方案,将感兴趣的条目组交织在一起,printbiblist为每个条目发布一个条目,并沿着手动提供的列表中提供的一组母条目循环。还引入了一些检查,以确保没有遗漏任何内容。

\RequirePackage{filecontents}

\begin{filecontents}{\jobname.bib}
@customa{natarch,
    title = {National Archives. But with a title long enough to span two lines. Yet a little longer},
    sortshorthand = {NatArch},
}

@customb{natarch:presabc,
    title = {President ABC Papers. A subtitle to let it reach a second line},
    shorthand = {NatArch -- ABC},
    sortshorthand = {NatArch -- ABC},
    xref = {natarch},
}

@customb{natarch:mintru,
    title = {Ministry of Truth Papers. Fully and continuously updated},
    shorthand = {NatArch -- MT},
    sortshorthand = {NatArch -- MT},
    xref = {natarch},
}

@customa{libcong,
    title = {Library of Congress},
    sortshorthand = {LibCon},
}

@customb{libcong:digcoll,
    title = {Digital Collections of the Library of Congress. But with a title long enough to span two lines},
    shorthand = {LibCon -- DC},
    sortshorthand = {LibCon -- DC},
    xref = {libcong},
}

\end{filecontents}

\documentclass{article}

\usepackage[style=authortitle,minxrefs=1]{biblatex}

\usepackage{calc}

\addbibresource{\jobname.bib}

% Providing bibdrivers

\DeclareBibliographyDriver{customa}{%
    \usebibmacro{bibindex}%
    \usebibmacro{begentry}%
    \printfield{title}%
    \newunit\newblock
    \printlist{location}%
    \usebibmacro{finentry}}
    
\DeclareBibliographyDriver{customb}{%
    \usebibmacro{bibindex}%
    \usebibmacro{begentry}%
    \printfield{title}%
    \usebibmacro{finentry}}

%Providing structure for biblist “primary”

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}
    
\DeclareBibliographyDriver{primary}{%
    \usedriver{}{\thefield{entrytype}}%
    \usebibmacro{finentry}}

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}

\DeclareSortingTemplate{primary}{
  \sort{
    \field{sortshorthand}
  }
  \sort{
    \field{shorthand}
  }
}

% Defining the two bibenvironments to be used in “primary” biblists

\defbibenvironment{primaryarchive}
  {\list
     {}
     {\setlength{\leftmargin}{\bibhang}%
      \setlength{\itemindent}{-\leftmargin}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}%
      \setlength{\topsep}{0pt}%
      \setlength{\partopsep}{2pt plus1pt minus1pt}}}
  {\endlist}
  {\item}

\defbibenvironment{primary}
  {\list
     {\printfield[shorthandwidth]{shorthand}}
     {\setlength{\labelwidth}{\shorthandwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{.5\bibhang}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}%
      \setlength{\topsep}{0pt}%
      \setlength{\partopsep}{0pt}%
      \renewcommand*{\makelabel}[1]{##1\hss}}}
  {\endlist}
  {\item}

% Providing structure for a check if entries have not been forgotten

\DeclareBibliographyCategory{primarysources}
\DeclareBibliographyCategory{alreadyinprimarylists}

\AtDataInput[customa]{\addtocategory{primarysources}{\thefield{entrykey}}}
\AtDataInput[customb]{\addtocategory{primarysources}{\thefield{entrykey}}}

\AtEveryBiblistitem{primary}{\addtocategory{alreadyinprimarylists}{\thefield{entrykey}}}

% The individual biblists are screened by keyword, this adds a keyword for both mother and child entrys equal to the entrykey of the mother entry

\DeclareSourcemap{
    \maps[datatype=bibtex]{
        \map[overwrite]{
            \pertype{customb}
            \step[fieldsource=xref]
            \step[fieldset=keywords,fieldvalue={,},append]
            \step[fieldset=keywords,origfieldval,append]
            \step[fieldsource=keywords,match=\regexp{^,},replace={}]
        }
        \map[overwrite]{
            \pertype{customa}
            \step[fieldsource=entrykey]
            \step[fieldset=keywords,fieldvalue={,},append]
            \step[fieldset=keywords,origfieldval,append]
            \step[fieldsource=keywords,match=\regexp{^,},replace={}]
        }
    }
}

% Provides commands to print mother and child entries for each group, and a command to iterate along them

\newcommand{\printarchive}[1]{%
    \printbiblist[env=primaryarchive,heading=none,type=customa,keyword=#1]{primary}
    \printbiblist[heading=none,type=customb,keyword=#1]{primary}%
}
\newcommand{\printarchives}[1]{%
    \forcsvlist{\printarchive}{#1}%
}

% Just formatting
\DeclareFieldFormat[customa,customb]{title}{#1}

\begin{document}

\nocite{libcong:digcoll,natarch:mintru,natarch:presabc}

% Prints primary sources
\printbibheading[title={Primary sources}]
\printarchives{libcong,natarch}

% Checks if nothing has been forgotten
\defbibnote{warningmissingprimsources}{\mkbibbold{These entries should have been printed in the primary sources biblists above. If their were not, they are listed here which means that something is amiss and these entries should be handled until this warning is gone.}}
\printbibliography[title={Missing primary sources},prenote=warningmissingprimsources,category=primarysources,notcategory=alreadyinprimarylists]

% For comparison
\printshorthands
\printbibliography

\end{document}

结果正如我们所期望的:

在此处输入图片描述

还缺少什么:

  • 母条目列表仍是手动提供的。这意味着我必须引入一些复杂的检查来处理最终的“杂散条目”。更重要的是,排序也是按照手动提供的列表的顺序进行的。可能有一种方法可以生成包含所有customa条目的列表,根据定义的排序方案对其进行排序并将其提供给printarchives。但我想不出。因此,正如最初所说的那样,其他完成此方法或完全采用另一种方法的答案仍然非常受欢迎。

更新:我找到了一种生成条目排序列表的方法customa。它涉及创建一个辅助printbiblist,其中包含 bibfilter、排序方案等,对该 biblist 进行错误运行并使用它来填充 etoolbox 列表,然后将其提供给printarchives。对于那些最终感兴趣的人:

\RequirePackage{filecontents}

\begin{filecontents}{\jobname.bib}
@customa{natarch,
    title = {National Archives. But with a title long enough to span two lines. Yet a little longer},
    sortshorthand = {NatArch},
}

@customb{natarch:presabc,
    title = {President ABC Papers. A subtitle to let it reach a second line},
    shorthand = {NatArch -- ABC},
    sortshorthand = {NatArch -- ABC},
    xref = {natarch},
}

@customb{natarch:mintru,
    title = {Ministry of Truth Papers. Fully and continuously updated},
    shorthand = {NatArch -- MT},
    sortshorthand = {NatArch -- MT},
    xref = {natarch},
}

@customa{libcong,
    title = {Library of Congress},
    sortshorthand = {LibCon},
}

@customb{libcong:digcoll,
    title = {Digital Collections of the Library of Congress. But with a title long enough to span two lines},
    shorthand = {LibCon -- DC},
    sortshorthand = {LibCon -- DC},
    xref = {libcong},
}

\end{filecontents}

\documentclass{article}

\usepackage[style=authortitle,minxrefs=1]{biblatex}

\usepackage{calc}

\addbibresource{\jobname.bib}

% Providing bibdrivers

\DeclareBibliographyDriver{customa}{%
    \usebibmacro{bibindex}%
    \usebibmacro{begentry}%
    \printfield{title}%
    \newunit\newblock
    \printlist{location}%
    \usebibmacro{finentry}}
    
\DeclareBibliographyDriver{customb}{%
    \usebibmacro{bibindex}%
    \usebibmacro{begentry}%
    \printfield{title}%
    \usebibmacro{finentry}}

%Providing structure for biblist “primary”

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}
    
\DeclareBibliographyDriver{primary}{%
    \usedriver{}{\thefield{entrytype}}%
    \usebibmacro{finentry}}

\DeclareBiblistFilter{primary}{
    \filteror{
        \filter[type=type,filter=customa]
        \filter[type=type,filter=customb]
    }
}

\DeclareSortingTemplate{primary}{
  \sort{
    \field{sortshorthand}
  }
  \sort{
    \field{shorthand}
  }
}

% Defining the two bibenvironments to be used in “primary” biblists

\defbibenvironment{primaryarchive}
  {\list
     {}
     {\setlength{\leftmargin}{\bibhang}%
      \setlength{\itemindent}{-\leftmargin}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}%
      \setlength{\topsep}{0pt}%
      \setlength{\partopsep}{2pt plus1pt minus1pt}}}
  {\endlist}
  {\item}

\defbibenvironment{primary}
  {\list
     {\printfield[shorthandwidth]{shorthand}}
     {\setlength{\labelwidth}{\shorthandwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{.5\bibhang}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}%
      \setlength{\topsep}{0pt}%
      \setlength{\partopsep}{0pt}%
      \renewcommand*{\makelabel}[1]{##1\hss}}}
  {\endlist}
  {\item}


% Provides structure for "auxiliary" biblist
% Used to generate a sorted list of customa (mother) entries

\DeclareBiblistFilter{auxiliary}{
        \filter[type=type,filter=customa]
}

\DeclareSortingTemplate{auxiliary}{
    \sort{
        \field{title}
    }
}

\DeclareBibliographyDriver{auxiliary}{}

\defbibenvironment{auxiliary}
  {\list
     {}
     {\setlength{\itemsep}{0pt}%
      \setlength{\parsep}{0pt}%
      \setlength{\topsep}{0pt}%
      \setlength{\partopsep}{0pt}}}
  {\endlist}
  {}

\AtEveryBiblistitem{auxiliary}{\listxadd{\sortedcustomalist}{\thefield{entrykey}}}

% The individual biblists are screened by keyword, this adds a keyword for both mother and child entrys equal to the entrykey of the mother entry

\DeclareSourcemap{
    \maps[datatype=bibtex]{
        \map[overwrite]{
            \pertype{customb}
            \step[fieldsource=xref]
            \step[fieldset=keywords,fieldvalue={,},append]
            \step[fieldset=keywords,origfieldval,append]
            \step[fieldsource=keywords,match=\regexp{^,},replace={}]
        }
        \map[overwrite]{
            \pertype{customa}
            \step[fieldsource=entrykey]
            \step[fieldset=keywords,fieldvalue={,},append]
            \step[fieldset=keywords,origfieldval,append]
            \step[fieldsource=keywords,match=\regexp{^,},replace={}]
        }
    }
}

% Provides an invisible box to perform false run of "auxiliary"
% from https://tex.stackexchange.com/a/22358/105447
\def\falserunbiblist#1{\edef\theprevdepth{\the\prevdepth}\nointerlineskip
  \vbox to0pt{#1\vss}\prevdepth=\theprevdepth}

% Provides commands to print mother and child entries for each group, and a command to iterate along them

\newcommand{\printarchive}[1]{%
    \printbiblist[env=primaryarchive,heading=none,type=customa,keyword=#1]{primary}
    \printbiblist[heading=none,type=customb,keyword=#1]{primary}%
}

\newcommand*{\sortedcustomalist}{}

\newcommand{\printarchives}{%
    \falserunbiblist{\printbiblist[heading=none]{auxiliary}} % This generates the list for the loop below
    \forlistloop{\printarchive}{\sortedcustomalist}
}

% Just formatting
\DeclareFieldFormat[customa,customb]{title}{#1}

\begin{document}

\nocite{libcong:digcoll,natarch:mintru,natarch:presabc}

% Prints primary sources
\printbibheading[title={Primary sources}]
\printarchives

% For comparison
\printshorthands
\printbibliography

\end{document}

答案2

我能够大大简化这个问题的解决方案(与https://tex.stackexchange.com/a/409970/105447)使用@moewe的方法biblatex 中集合成员的缩进,这使得我们可以在 bibenvironment 中有一个子列表(在本例中,放在 bibdriver 中)。

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@customa{natarch,
  title = {National Archives. But with a title long enough to span two lines. Yet a little longer.},
  sortkey = {NatArch},
}

@customb{natarch:presabc,
  title = {President ABC Papers. A subtitle to let it reach a second line.},
  shorthand = {NatArch -- ABC},
  sortkey = {NatArch -- ABC},
  xref = {natarch},
}

@customb{natarch:mintru,
  title = {Ministry of Truth Papers. Fully and continuously updated.},
  shorthand = {NatArch -- MT},
  sortkey = {NatArch -- MT},
  xref = {natarch},
}

@customa{libcong,
  title = {Library of Congress},
  sortkey = {LibCon},
}

@customb{libcong:digcoll,
  title = {Digital Collections of the Library of Congress. But with a title long enough to span two lines.},
  shorthand = {LibCon -- DC},
  sortkey = {LibCony -- DC},
  xref = {libcong},
}
\end{filecontents}

\usepackage[style=authortitle,minxrefs=1,locallabelwidth=true]{biblatex}
\addbibresource{\jobname.bib}

\DeclareBibliographyDriver{customa}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \printfield{title}%
  \usebibmacro{finentry}}

\newenvironment{subbiblist}
  {\begin{list}
      {\printfield[shorthandwidth]{shorthand}}%
      {\setlength{\labelwidth}{\shorthandwidth}%
      \setlength{\leftmargin}{\labelwidth}%
      \setlength{\labelsep}{\biblabelsep}%
      \addtolength{\leftmargin}{\labelsep}%
      \setlength{\itemsep}{\bibitemsep}%
      \setlength{\parsep}{\bibparsep}%
      \renewcommand*{\makelabel}[1]{##1\hss}}}
  {\end{list}}

\makeatletter
\DeclareBibliographyDriver{customb}{%
  \usebibmacro{bibindex}%
  % from https://tex.stackexchange.com/a/463414/105447
  % don't issue \leavevmode inside here
  \let\blx@leavevmode\relax
  % get rid of the \leavevmode from the beginning of the entry
  % this avoids an empty line before the enumerate
  \vspace{-\dimexpr\baselineskip+\itemsep\relax}%
  \begin{subbiblist}
    \item
    \usebibmacro{begentry}%
    \printfield{title}%
    \usebibmacro{finentry}%
  \end{subbiblist}%
}
\makeatother

\begin{document}

\nocite{*}
\printbibliography

\end{document}

在此处输入图片描述

相关内容