
問題
我正在創建一個自訂 biblatex 樣式,並且希望支援類似於該month
欄位在常見實作中所具有的 bibstrings。也就是說,如果我將某些內容放在括號中{something}
,內容something
會呈現在欄位中。但是,如果我有一些沒有括號的東西,它會被解釋為 bibstring 並轉換為其定義。
\ifbibstring
我可以透過(和朋友)檢查該欄位的內容是否是一個 bibstring 來部分實現這一點。但是,只有當內容始終位於括號內時才有效。如果不是 biber,則會給出錯誤,並且不會透過該欄位進行進一步處理。
例如,下面的程式碼產生警告訊息
警告 - BibTeX 子系統:/tmp/M3YJZ8wGD7/mwe.bib_28410.utf8,第 21 行,警告:未定義的巨集“mytitle”
這使得 biber 不會在.bbl
文件中建立該欄位。我發現了類似的錯誤biblatex/biber:在多個參考部分中使用一個檔案中的字串宏,但這並不能解決我的問題。
微量元素
這是我展示我的問題的最小實現。
% !BIB program = biber
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@test{test1,
title = {A},
year = {1995},
}
@test{test2,
title = {B},
year = {1994},
}
@test{test3,
title = {mytitle},
year = {1998},
}
@test{test4,
title = mytitle,
year = {1998},
}
\end{filecontents}
\begin{filecontents}{test.dbx}
\DeclareDatamodelFields[type=field, datatype=literal]{title}
\DeclareDatamodelFields[type=field, datatype=datepart]{year}
\DeclareDatamodelEntryfields[test]{%
year,%
title%
}
\end{filecontents}
\begin{filecontents}{english-test.lbx}
\InheritBibliographyExtras{english}
% Bibliography strings
\NewBibliographyString{mytitle}
\DeclareBibliographyStrings{%
inherit = {american},
mytitle = {{my title}{my title}},
}
\end{filecontents}
\begin{filecontents}{test.bbx}
\RequireBibliographyStyle{standard}
% map language
\DeclareLanguageMapping{english}{english-test}
% Dummy driver for testing
\DeclareBibliographyDriver{test}{%
\usebibmacro{begentry}%
\printfield{title}%
\newunit%
\printfield{year}%
\newunit%
\usebibmacro{finentry}%
}
\DeclareFieldFormat[test]{title}{%
\ifbibstring{#1}{\bibstring{#1}}{#1}%
}
\end{filecontents}
\usepackage[backend=biber, bibstyle=test]{biblatex}
\addbibresource{\jobname.bib}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
電流輸出:
預期輸出:
問題
請注意,我期望與像這樣的 bibstrings 具有相同的行為month
。如果我的欄位沒有括號,則應test4
使用.bib
bibstring 的定義進行轉換。但是,如果我有相同的括號的定義,例如 in test3
,則應列印內容。
如何透過自訂樣式實現這一目標?
答案1
這裡至少有兩個「字串」的概念。本身也沒有你想要的。只有兩者的結合才能做到這一點。
@string
s
首先,有@string
.@string
是一種將相同文字插入多個.bib
條目的方法,而無需每次都重新鍵入整個文字。此功能完全在.bib
檔案層級起作用。
條目@string
有一個 ID(就像普通條目的輸入鍵一樣.bib
)並且可以透過該名稱進行呼叫。
@string{brontostring = {On the Theory of Brontosauruses}}
@string
可以透過將字串 ID 作為欄位值來使用a 的內容沒有大括號。
@book{foo,
author = {Anne Elk},
title = brontostring,
date = {1970},
}
Biber(或 BibTeX)在讀取.bib
檔案時立即解析這些字串。需要注意的是,@string
必須先定義 s,然後才能使用它們。特別是,您不能使用不帶大括號的任意文本,只能使用已知的@string
文字。然後我們剩下
@book{foo,
author = {Anne Elk},
title = {On the Theory of Brontosauruses},
date = {1970},
}
當進一步處理該條目時,沒有任何跡象表明該文本源自@string
.
這將允許您將任意文字插入條目中。文字不能通過 更改,但您可以透過載入對同一字串具有不同定義的biblatex
不同檔案來更改它。.bib
這就是and 的ieeetran
作用。您可以載入以取得縮寫的期刊名稱或取得完整的期刊名稱。IEEEabrv.bib
IEEEfull.bib
IEEEabbrv.bib
IEEEfull.bib
對於所有意圖和目的,月份字串都以類似的方式工作。
jan
是一個@string
for 1
、feb
for2
等等。
@string
.bib
當它們用作字段值時,不要在文件中使用大括號。
參考書目字串
然後還有第二個完全不相關的「字串」概念,即 bibstrings。這些是您用\ifbibstring
,\bibstring
和引用的那些\NewBibliographyString
。 Bibstrings 是biblatex
在地化功能的一部分,可讓您將某些術語翻譯成其他語言。通常它們在檔案中定義.lbx
,但它們的值也可以在前導碼中被覆寫。
書目字串可以與 一起使用,\bibstring{<bibstringid>}
其中<bibstringid>
是用 定義的書目字串的名稱\NewBibliographyString
。理想情況下,<bibstringid>
也會在.lbx
文件中收到一個值,否則<bibstringid>
以粗體列印。
整個日期處理要複雜得多,但對於這個答案,我們可以假設biblatex
有一個名為的函數,\mkbibmonth
該函數將 1 映射到\bibstring{january}
, 2 映射到\bibstring{february}
等。 因此,當\mkbibmonth{7}
調用時,這會導致\bibstring{july}
'July' 打印在您的文檔中(如果是英文)是活動語言,如果德語是活動語言,則為「Juli」。
bibstrings 的一個更簡單、更典型的例子是pubstate
欄位。的欄位格式pubstate
為
\DeclareFieldFormat{pubstate}{\ifbibstring{#1}{\bibstring{#1}}{#1}}
您可以在該pubstate
欄位中使用一些預先定義的字串,例如
inpress
, forthcoming
, submitted
。如果您使用其中之一,即您有
pubstate = {inpress},
在您的條目之一中.bib
,則biblatex
不會在文件中列印“inpress”,而是使用書目字串中給出的該術語的翻譯。 (當然,biblatex
我很樂意使用您提供的任何其他書目字串,也pubstate = {january}
可以工作。)如果沒有具有該名稱的書目字串,則該欄位將按原樣列印,因此pubstate = {foonostring}
只需列印「foonostring」。
bibstrings
文件中的輸入始終.bib
帶有大括號。
兩種字串類型的比較
據我所知,沒有其他@strings
和 bibstrings的組合biblatex
以完全相同的方式工作。我強烈懷疑月份@string
只是出於向後相容性的原因而實現的。
正如我們所看到的,通常有兩種方法可以建立上下文相關的輸出。
@string
由後端解決- (
.lbx
) 書目字串解析為biblatex
哪一種更合適取決於您的用例。
@string
如果您只是想節省打字時間,或者如果您想有辦法在多種輸入形式(長日誌名稱與短日誌名稱)之間切換,則 s 似乎更合適。一般來說,@string
s 與語言或區域設定無關。如果您想要真正的在地化,Bibstrings 是您的最佳選擇。
我無法透過您問題中的範例來判斷這兩種方法中哪一種在您的用例中更有用。
我們能得到你想要的嗎?
如果您堅持問題中描述的方案,那麼透過結合這兩種方法幾乎是可能的。我認為這不是一個特別好的主意,但我們走吧。
對於每個不帶大括號的可能值,您需要定義@string
帶有替換文字的 a 。如果您想要一個可移植的解決方案,則需要在一個特殊檔案中完成.bib
,您需要在所有專案中載入該檔案。
@string{bracelessa = {bracelessa}}
@string{bracelessb = {bracelessb}}
然後製作 bibstring bracelessa
,bracelessb
已知biblatex
\NewBibliographyString{bracelessa}
\NewBibliographyString{bracelessb}
並定義它們
\DeclareBibliographyStrings{%
inherit = {american},
bracelessa = {{A title}{A t\addddot}},
bracelessb = {{B title}{B t\addddot}},
}
然後使用欄位格式
\DeclareFieldFormat[test]{title}{\ifbibstring{#1}{\bibstring{#1}}{#1}}
對於有問題的領域。
現在
title = bracelessa,
將在您的文件中列印“A title”。
為什麼這不能準確地給出你所描述的內容?
首先,無括號輸入不是任意的。您需要定義 a@string
和適當的bibstring
.其次,title = {something}
不會一直渲染something
。如果你寫title = {bracelessa}
“A title”,就會出現。透過為 bibstrings 選擇更荒謬的名稱可以使衝突變得更加困難,但它們總是可能的,因為無法確定欄位值是直接給出還是透過@string
.