如何使用 biblatex 和 biber 检测传递给自定义 cite 命令的引用键数量

如何使用 biblatex 和 biber 检测传递给自定义 cite 命令的引用键数量

我正在研究如何利用biblatex+biber灵活性和模块化来创建引用系统以引用法律条款(法律、法令等的部分内容)。为此,我创建了自定义数据模型、参考书目驱动程序的(粗略)草稿,现在我正在研究自定义引用命令。

遗憾的是,这让 MWE 变得相当冗长。

我想知道,是否有可能检测出传递给自定义cite命令,以改变输出。规则:

  1. 1钥匙, 不用找了
  2. 2钥匙s,单独引用和文本(例如" and":)
  3. 3钥匙s,单独引用空间逗号
  4. 4 个或以上钥匙s,压缩引用,只在正文中打印第一个和最后一个,其他的只放在参考书目中

这是我想要实现的一套完整的规则,但实际上,如果能够检测到钥匙传递给cite命令,如果有人能帮助我,并提示我如何进行第 2 步,我很乐意将第 3 步和第 4 步作为练习来执行。

梅威瑟:

% arara: lualatex
% arara: biber
% arara: lualatex
% arara: biber
% arara: lualatex

\documentclass [a4paper, 11pt, twoside, openright, czech]{scrbook}          
\usepackage [czech,shorthands=off] {babel}                          
\usepackage{fontspec}
\usepackage{filecontents}

\usepackage{expl3}
\usepackage{xparse}

\usepackage{lmodern}
\usepackage{csquotes}

\begin{filecontents}{speclegislation.dbx}
\DeclareDatamodelEntrytypes{speclegislation}
\DeclareDatamodelFields[type=field,datatype=literal]{
  dokument,
  zkracene,
  number,
  year,
  title,
  paragraf,
  odstavec,
  pismeno,
  sortkey,
}
\DeclareDatamodelEntryfields[speclegislation]{
  dokument,
  zkracene,
  number,
  year,
  title,
  paragraf,
  odstavec,
  pismeno,
  keywords,
  sortkey,
}
\end{filecontents}

\usepackage[style=numeric, backend=biber, datamodel=speclegislation, refsegment=chapter, defernumbers=true, mincrossrefs=1, backref=true, backrefstyle=three, sorting=none]{biblatex}

\newbibmacro{dokumentnumberyeartitle}{
  \printfield{dokument}%
  \newunit
  \printfield{number}%
  \newblock
  \printfield{year}%
  \newunit
  \printfield{title}
}

\newbibmacro{paragrafodstavecpismeno}{
  \printfield{paragraf} %
  \nopunct\newunit
  \printfield{odstavec} %
  \nopunct\newunit
  \printfield{pismeno}%
}

\DeclareBibliographyDriver{speclegislation}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \usebibmacro{dokumentnumberyeartitle}
  \nopunct\newunit
  \usebibmacro{paragrafodstavecpismeno}
  \nopunct\newunit
  \usebibmacro{pageref}%
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

\DeclareSourcemap{
  \maps[datatype=bibtex,overwrite=true]{
    \map{
      \pertype{speclegislation}
      \step[fieldsource=paragraf]
      \step[fieldset=sortkey, origfieldval]
    }
  }
}

\DeclareFieldFormat{dokument}{#1\addspace}
\DeclareFieldFormat{number}{#1/}
\DeclareFieldFormat{year}{#1\addnbspace Sb.,\addspace}
\DeclareFieldFormat{title}{#1\addspace}
\DeclareFieldFormat{paragraf}{§\addnbspace#1\addspace}
\DeclareFieldFormat{odstavec}{odst.\addnbspace#1\addspace}
\DeclareFieldFormat{pismeno}{písm.\addnbspace#1)\addspace}
\DeclareFieldFormat{zkracene}{#1\addspace}

\renewcommand{\finentrypunct}{}

\DefineBibliographyStrings{czech}{
  bibliography = {Reference},
}

\begin{filecontents}{citace.bib}
@speclegislation{v21p12pa,
paragraf = {12},
pismeno = {a},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21p12pb,
paragraf = {12},
pismeno = {b},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21p12pc,
paragraf = {12},
pismeno = {c},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21p12pd,
paragraf = {12},
pismeno = {d},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21p12pe,
paragraf = {12},
pismeno = {e},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21p12pf,
paragraf = {12},
pismeno = {f},
keywords = {vyhlaska21},
crossref = {v21}
}

@speclegislation{v21,
dokument = {Vyhláška},
zkracene = {v.},
number = {21},
year = {2017},
title = {o zajišťování jaderné bezpečnosti JZ},
keywords = {vyhlaska21}
}
\end{filecontents}
\addbibresource{citace.bib}

\DeclareCiteCommand{parvcite}
    {\usebibmacro{prenote}}
    {\usebibmacro{citeindex}%
    \usebibmacro{paragrafodstavecpismeno}\printfield{zkracene}\printfield{number}\printfield{year}%
    \printtext[bibhyperref]{%
      \printfield{labelprefix}%
      \mkbibbrackets{\printfield{labelnumber}}}%
     }
    {\addcomma\addspace}
    {\usebibmacro{postnote}}

\ExplSyntaxOn

\NewDocumentCommand{\mycite}{ O{} O{} m }{
\parvcite{#3}
}

\ExplSyntaxOff

\begin{document}
Citation testing:

Current output:

1 \textit{key} citation:
\mycite{v21p12pa}

\medskip

2 \textit{keys} citation

\mycite{v21p12pa, v21p12pb}

Desired output:

\mycite{v21p12pa} and \mycite{v21p12pb}

\medskip

3 \textit{key} citation:

\mycite{v21p12pa, v21p12pb, v21p12pc}

Desired output:

\mycite{v21p12pa}, \mycite{v21p12pb}, \mycite{v21p12pc}

\medskip

4 or more \textit{key}s citation:

\mycite{v21p12pa, v21p12pb, v21p12pc, v21p12pd}

Desired output:

\mycite{v21p12pa} \nocite{v21p12pb} \nocite{v21p12pc} – \mycite{v21p12pd}

\clearpage

\printbibliography
\end{document}

附言:部分文本是捷克语,希望您不介意。另外,mycite命令“准备”变得更复杂/更复杂,这就是为什么它被定义为xparse带有 2 个可选参数和 1 个强制参数的原因。

答案1

biblatex\...cite存储当前调用中引用的输入键数citetotal和当前键的数目citecount。使用这两个计数器,您应该能够实现您想要的功能。

请注意,还有multicitetotalmulticitecount来计数多引用命令中的输入键组的数量\...cites

biblatex\iffirstcitekey{<true>}{<false>}提供了开箱即用的测试\iflastcitekey{<true>}{<false>},因此您不必为这些常见情况编写数字比较测试,但是在下面的示例中我不会使用这两个命令。

以下 MWE 演示了如何citecountcitetotal简化设置中使用。

\documentclass[british]{article}
\usepackage[T1]{fontenc}
\usepackage{babel}
\usepackage{csquotes}

\usepackage[style=numeric, backend=biber]{biblatex}

\addbibresource{biblatex-examples.bib}

\newcommand*{\mycitedelim}{%
  \ifnumgreater{\value{citetotal}}{2}
    {\addcomma\space}
    {\addspace\bibstring{and}\space}}

\newbibmacro*{mycite}{%
  \ifboolexpr{
       test {\ifnumequal{\value{citecount}}{1}}
    or test {\ifnumequal{\value{citecount}}{\value{citetotal}}}
    or test {\ifnumless{\value{citetotal}}{4}}}
    {\printtext[bibhyperref]{%
       \printfield{labelprefix}%
       \printfield{labelnumber}%
       \ifbool{bbx:subentry}
         {\printfield{entrysetcount}}
         {}}}
    {}}

\DeclareCiteCommand{\mycite}[\mkbibbrackets]
  {\usebibmacro{prenote}}
  {\usebibmacro{citeindex}%
   \usebibmacro{mycite}}
  {\setunit{\mycitedelim}}
  {\usebibmacro{postnote}}

\begin{document}
\mycite{sigfridsson}

\mycite{sigfridsson,nussbaum}

\mycite{sigfridsson,nussbaum,worman}

\mycite{sigfridsson,nussbaum,worman,geer}

\mycite{sigfridsson,nussbaum,worman,geer,cicero}

\printbibliography
\end{document}

[4]//[4 和 3]//[4, 3, 5]//[4, 2]//[4, 1]

请注意,如果您希望正确压缩引文,则需要更复杂的方法,实际检查输出标签是否可以压缩(您可以将“12a、12b、12c、12d”压缩为“12a-12d”或“12a-d”,但不能将“12a、12b、14a、14e”压缩为“12a-14e”或“12a-e”)。这是在numeric-comp.cbx对于简单的标签编号,但在您的使用案例中它可能会更加复杂。

相关内容