我需要告诉 LaTeX,当通过 crossref 引用与 Collection 相关的 Incollection 时:如果这不是该 Collection 的第一次引用,则使用此驱动程序而不是通常的驱动程序。
那可能吗?
MNWE 使用下面建议的代码(我不知道为什么它不能与里面的参考书目文件一起运行。顺便说一句,如果没有文件内容,它可以运行,但仍然不能按预期工作)
% !BIB TS-program = biber
% !BIB program = biber
% !TEX encoding = UTF-8 Unicode
% !TeX TS-program = xelatexmk
\begin{filecontents}{archivio.bib}
@collection{Col4,
Editor = {Gino Autieri AND Gaspare Porro},
Publisher = {Routledge},
Shorttitle = {The Grand Theater},
Title = {The Grand Theater of the World. Music, Space, and the Performance of Identity in Early Modern Rome},
Year = {2019}}
@incollection{Inc4,
Author = {Mario Rossi AND Giovanni Bianchi},
Crossref = {Col3},
Pages = {151-163},
Title = {Cultural Life at Villa Lante di Bagnaia. Family, gardens and sociability},
Shorttitle = {Cultural Life}}
@book{rompi,
Author = {Pippo Kennedy},
Publisher = {Routledge},
Title = {Questo è un libro per rompere l'ibidem},
Year = {2019}}
\end{filecontents}
\documentclass[10pt, twoside, openany]{book}
\usepackage[paperwidth=210mm, paperheight=150mm, inner=5mm, outer=5mm, top=5mm, bottom=5mm]{geometry}
\usepackage{fontspec}
\usepackage{polyglossia}
\setmainlanguage{italian}
\usepackage[autostyle,italian=guillemets]{csquotes}
\usepackage{xpatch}
\usepackage{etoolbox} % necessario per il comando custom per le citazioni di incollection in crossref
\usepackage[style=verbose-trad2,
language=italian,
useprefix=true,
% giveninits=true, nomi per esteso
indexing=true,
maxbibnames=7,
maxcitenames=2,
citepages=omit,
backend=biber,
ibidpage=true,
]{biblatex}
% \usepackage{biblatex-opcit-booktitle} % per avere cit. nelle citazioni di Incollection con crosserf > non funziona in tutti i casi quindi lo commento
\NewBibliographyString{ibidemloccit,ibidemnoloccit}
\DefineBibliographyStrings{italian}{%
idem = {Id\adddot},
idemsm = {Id\adddot},
idemsf = {Ead\adddot},
idemsn = {Id\adddot},
idempm = {Id\adddot},
idempf = {Id\adddot},
idempn = {Id\adddot},
idempp = {Id\adddot},
ibidemloccit = {Ibidem}, % tolto \mkbibemph perché ho già che tutte le latinitates sono enfatiche; Se capiterà di dover avere la "i" minuscola, bisogna mettere minuscolo nel codice e distinguere tra \cite e \Cite
ibidemnoloccit = {Ivi},
editor = {a cura di},
editors = {a cura di}
}
\xpatchbibmacro{author}
{\printnames{author}}
{\iffootnote
{\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
{\usebibmacro{cite:idem}}
{\printnames{author}}}
{\printnames{author}}}
{}{}
\xpatchbibmacro{bbx:editor}
{\printnames{editor}}
{\iffootnote
{\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
{\usebibmacro{cite:idem}}
{\printnames{editor}}}
{\printnames{editor}}}
{}{}
\xpatchbibmacro{bbx:translator}
{\printnames{translator}}
{\iffootnote
{\ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}
{\usebibmacro{cite:idem}}
{\printnames{translator}}}
{\printnames{translator}}}
{}{}
\renewbibmacro*{cite:ibid}{%
\printtext{%
\bibhyperlink{cite\csuse{cbx@lastcite@\thefield{entrykey}}}{%
\ifloccit
{\bibstring[\mkibid]{ibidemloccit}%
\global\toggletrue{cbx:loccit}}
{\bibstring[\mkibid]{ibidemnoloccit}}}}}
\renewbibmacro*{cite:title}{% Ciò che segue è per avere lo shorttitle alla seconda citazione (funge solo in trad2)
\printtext[bibhyperlink]{%
\printfield[citetitle]{labeltitle}%
\setunit{\addspace}%
\bibstring[\mkibid]{opcit}}}
%%%%%%%%%%%%%%% COMANDI PER CITAZIONE DI INCOLLECTION CON CROSSREF %%%%%%%%%%
\makeatletter
% test to check if we are dealing with an @incollection
% which has a crossref that was cited before
\newcommand*{\ifincollectioncrossrefparentseen}{%
\ifentrytype{incollection}
{\iffieldundef{crossref}
{\@secondoftwo}
{\ifciteseen{\thefield{crossref}}}}
{\@secondoftwo}}
\makeatother
\renewbibmacro*{cite:full}{%
\usebibmacro{cite:full:citepages}%
\printtext[bibhypertarget]{%
\ifincollectioncrossrefparentseen
{\usedriver
{\DeclareNameAlias{sortname}{default}}
{special:incollection}}
{\usedriver
{\DeclareNameAlias{sortname}{default}}
{\thefield{entrytype}}}}%
\usebibmacro{shorthandintro}}
%%%%%%%%%%%%%% RIDEFINISCO IL DRIVER COLLECTION%%%%%%%%%%%%
\DeclareBibliographyDriver{collection}{%
\usebibmacro{bibindex}%
\usebibmacro{begentry}%
\usebibmacro{maintitle+title}%
\setunit{\printdelim{nametitledelim}}\newblock
\usebibmacro{byeditor+others}%
\newunit\newblock
\usebibmacro{editor+others}%
\newunit
\printlist{language}%
\newunit\newblock
\printfield{edition}%
\newunit
\iffieldundef{maintitle}
{\printfield{volume}%
\printfield{part}}
{}%
\newunit
\printfield{volumes}%
\newunit\newblock
\usebibmacro{series+number}%
\newunit\newblock
\printfield{note}%
\newunit\newblock
\usebibmacro{publisher+location+date}%
\newunit\newblock
\usebibmacro{chapter+pages}%
\newunit
\printfield{pagetotal}%
\newunit\newblock
\iftoggle{bbx:isbn}
{\printfield{isbn}}
{}%
\newunit\newblock
\usebibmacro{doi+eprint+url}%
\newunit\newblock
\usebibmacro{addendum+pubstate}%
\setunit{\bibpagerefpunct}\newblock
\usebibmacro{pageref}%
\newunit\newblock
\iftoggle{bbx:related}
{\usebibmacro{related:init}%
\usebibmacro{related}}
{}%
\usebibmacro{finentry}}
\addbibresource{archivio.bib}
%%%%%%%%%%%%%%%%%%%%
\begin{document}
\textbf{Collection first cite} -> everythong long\\
\cite{Col4}\\
Rompitraccia: \cite{rompi}\\
\textbf{Incollection first cite} -> Incollection long and Collection short\\
\cite{Inc4}\\
Something in the middle (for the ibidem): \cite{rompi}\\
\textbf{Incollection second cite} -> Just the short Incollection\\
\cite{Inc4}
答案1
通常verbose
样式在宏的引用中调用参考书目驱动程序cite:full
,其定义通常大致如下(此处的代码示例来自verbose.cbx
)
\newbibmacro*{cite:full}{%
\usebibmacro{cite:full:citepages}%
\printtext[bibhypertarget]{%
\usedriver
{\DeclareNameAlias{sortname}{default}}
{\thefield{entrytype}}}%
\usebibmacro{shorthandintro}}
\usedriver{<precode>}{<entry type>}
执行<precode>
,然后调用驱动程序<entry type>
。
严格来说,<entry type>
不需要是现有的条目类型,它可以是你定义的任何驱动程序。例如,你可以@incollections
为
\DeclareBibliographyDriver{special:incollection}{%
...
}
然后调用
\usedriver
{\DeclareNameAlias{sortname}{default}}
{special:incollection}
现在您需要一种方法来测试是否要使用特殊驱动程序。
如果我理解正确的话,您正在考虑这样一种情况:您有一个,@incollection
它crossref
是它的父级@collection
,现在您想确定它是否@collection
之前被见过。
您需要的测试是\ifentryseen{<entrykey>}{<true>}{<false>}
\ifentryseen{\thefield{crossref}}
{<parent cited already}
{<parent not cited already>}
请注意,此测试只能在@collection
引用父级时进行检测,而不能在之前在其他上下文中看到它时进行检测(可能是因为其他@incollection
条目已经提到过它)。如果您想在其他上下文中检测对父级的提及@collection
,则需要一些更高级的跟踪,您可能需要自己编写代码。
你可以把它组合成类似这样的
\makeatletter
% test to check if we are dealing with an @incollection
% which has a crossref that was cited before
\newcommand*{\ifincollectioncrossrefparentseen}{%
\ifentrytype{incollection}
{\iffieldundef{crossref}
{\@secondoftwo}
{\ifentryseen{\thefield{crossref}}}}
{\@secondoftwo}}
\makeatother
\renewbibmacro*{cite:full}{%
\usebibmacro{cite:full:citepages}%
\printtext[bibhypertarget]{%
\ifincollectioncrossrefparentseen
{\usedriver
{\DeclareNameAlias{sortname}{default}}
{special:incollection}}
{\usedriver
{\DeclareNameAlias{sortname}{default}}
{\thefield{entrytype}}}}%
\usebibmacro{shorthandintro}}
一般来说,当您为同一条目类型创建两个非常相似的参考书目驱动程序时,我预计会产生不必要的开销和代码重复。我预计,只需对驱动程序本身进行编码,使其根据测试以不同的方式显示结果,会稍微简单一些\ifincollectioncrossrefparentseen
。