我有一堆同一位作者的 bib 条目,它们都标有完整日期。问题是其中一些条目的日期相同,因此需要一个 extrayear 标签。但 extrayear 按年份工作,而不是按完整日期工作。所以看起来我只能标记所有条目或不标记任何条目。有人知道在下面的例子中,两个中间条目如何获得标签“a”和“b”,而其他条目没有标签吗?
\documentclass[fontsize=11pt,parskip=half]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[backend=biber,
style=authoryear-ibid,
datelabel=short,
]{biblatex}
\addbibresource{testextra.bib}
%\AtEveryBibitem{\iffieldundef{day}{}{\clearfield{extrayear}}{}}
%\AtEveryCitekey{\iffieldundef{day}{}{\clearfield{extrayear}}{}}
\begin{document}
abc\nocite{*}
\printbibliography
\end{document}
Bib(已编辑,包含两个不相关的条目,不应受到影响)。
@article{authorA1,
author={authorA},
title={blaa},
date={2014-03-03}
}
@article{authorA2,
author={authorA},
title={blab},
date={2014-03-04}
}
@article{authorA3,
author={authorA},
title={blac},
date={2014-03-04}
}
@article{authorA4,
author={authorA},
title={blad},
date={2014-03-05}
}
@article{gambol,
author={Gambolputty, Johann},
title={Titel},
year={1970}}
@book{authorB,
author={authorB},
title={Titel},
date={2010-10}}
答案1
随着新的\DeclareExtradate
(见https://github.com/plk/biblatex/issues/540biblatex
) 在3.8/Biber 2.8中引入,你只需要
\DeclareExtradate{%
\scope{
\field{labelyear}
\field{year}
}
\scope{
\field{labelmonth}
}
\scope{
\field{labelday}
}
}
由于您使用的日期格式已将extradate
字段(以前称为extrayear
)放入正确的位置,我们甚至不需要更改日期宏。如果需要不同的输出,可能需要修改日期打印宏2017-02-27b
。
答案2
我尝试创建一个独立的 Lua 模块来修复该bbl
文件。排序在这里不是问题,它使用通用year-month-day
格式。在此示例中,我们尝试获取从a,b,c,d
到 的一系列,a,b,
。我们需要提前搜索,否则我们将获得一系列a,a,b,a
。我决定更改系列的排序键是namehash
+ year
+ month
+ day
,它是来自文件的字段的组合bbl
。该算法可以简要描述如下:
- 如果两个连续日期不相等,请注释掉第一行。
- 如果是,请使用计数器并修改两行中该字段的数字(这是第二个 TeX 参数),例如修改为 1 和 2、2 和 3...
- 如果没有年、月、日数据,则故意跳过某个条目。
编辑:year
由于使用了排序键,我们得到了、year
+month
和year
++的单独系列。我已通过添加默认值修复了修复程序,因此如果没有或数据,month
它就可以正常工作。day
month
day
在我们的示例中,我们将在前四次出现时获得更改extrayear
(这是以前的版本,请参阅修订列表):
\字段{额外年份}{1}
\字段{额外年份}{2}
\字段{额外年份}{3}
\字段{额外年份}{4}
到
%\field{额外年份}{1}
\field{额外年份}{1}%2
\field{额外年份}{2}%3
%\field{额外年份}{4}
编辑:extrayear
出于安全原因,在新版本中添加了新字段而不是进行更改,例如\field{userb}{1}
。
我们可以比较使用修复程序之前和之后的结果:
笔记:我认为文本中的引用应该以某种方式进行修复(希望在级别上biblatex
),它看起来不对,因为我们可以发现AuthorA 2014
两次,但针对两本不同的书。如果我们使用\nocite{*}
,那就没问题了。Ulrike Fischer 建议重新定义\cite
命令。
我正在以这种方式使用所谓的修复程序(Lua 独立库):
lualatex mal-biber
biber mal-biber
luatex --luaonly mal-fixer.lua mal-biber
lualatex mal-biber
如果一切正常,您可能会在终端中发现两行:
Mal-fixer 正在处理 mal-biber.bbl 文件...
Mal-fixer 已完成 12 项任务!
虽然我运行的是lualatex
,但任何 LaTeX 格式都可以使用。我附上了主要的 TeX 代码和 Lua 库。
%! *latex mal-biber.tex
\documentclass[fontsize=11pt,parskip=half]{scrartcl}
\pagestyle{empty}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[ngerman]{babel}
\usepackage[backend=biber,
style=authoryear-ibid,
datelabel=short,
]{biblatex}
\usepackage{etoolbox}
\usepackage{filecontents}
\def\malfile{testextra1.bib}
\begin{filecontents*}{\malfile}
@article{authorA4,
author={AuthorA},
title={blad},
date={2014-03-05},
}
@article{authorA3,
author={AuthorA},
title={blac},
date={2014-03-04},
}
@article{authorA2,
author={AuthorA},
title={blab},
date={2014-03-04},
}
@article{authorA1,
author={AuthorA},
title={blaa},
date={2014-03-03},
}
@article{gambol,
author={Gambolputty, Johann},
title={Titel},
year={1970},
}
@article{gambolb,
author={Gambolputty, Johann},
title={Titel},
year={1970},
}
@book{authorBa,
author={AuthorB},
title={Titel},
date={2010-10},
}
@book{authorBb,
author={AuthorB},
title={Titel},
date={2010-10},
}
@book{authorBc,
author={AuthorB},
title={Titel},
date={2010-11},
}
@book{authorBd,
author={AuthorB},
title={Titel},
date={2010-11},
}
@book{authorC,
author={AuthorC},
title={Titel},
}
@book{authorD,
author={AuthorD},
title={Titel},
date={},
}
\end{filecontents*}
\addbibresource{\malfile}
%\ifx\relax % An updated version...
\AtEveryBibitem{% A tip for using \savefield->\restorefield by Ulrike Fischer...
\iffieldundef{extrayear}{}{%
\clearfield{extrayear}%
\iffieldequalstr{userb}{}{}{\savefield{userb}{\myusera}%
\restorefield{extrayear}{\myusera}}%
}% End of testing extrayear...
}% End of \AtEveryBibitem...
%\AtEveryCitekey{}
%\fi
\begin{document}
\nocite{*}
\ifx\relax % The \cite command must be redefined to fit those three fields...
% A tip by Ulrike Fischer: \mkbibdateshort{labelyear}{labelmonth}{labelday}
The regular paragraph\ldots\par
\cite{authorA4}\par\cite{authorA3}\par\cite{authorA2}\par\cite{authorA1}\par
\cite{gambol}\par\cite{gambolb}\par
\cite{authorBa}\par\cite{authorBb}\par\cite{authorBc}\par\cite{authorBd}\par
\cite{authorC}\par\cite{authorD}\par
\fi
\printbibliography
\end{document}
该库是这个文件:
-- I am a mal-fixer.lua file, version 3 from 2014-04-04...
-- I am fixing extrayear in the bbl file...
---- Common usage: ----
-- lualatex mal-biber
-- biber mal-biber
-- luatex --luaonly mal-fixer.lua mal-biber
-- lualatex mal-biber
local name=arg[1] -- Get me a name from the command line...
if string.sub(name,-4)~=".bbl" then name=name..".bbl" end -- Add me an extension if I don't have one
--print(name) -- Show me the name of the file...
--do return end -- Quick exit of Lua...
print("\nMal-fixer is processing the "..name.." file...") -- Information sent to the terminal...
local myfile=io.open(name,"r") -- Read the file...
local content=myfile:lines() --("*a")
local mybackup=io.open(name.."-backup","w") -- Open me as a backup file...
local saved={} -- Storage of all data...
local mal=0 -- A counter of \entry commands...
for oneline in content do -- The main cycle over lines...
mybackup:write(oneline.."\n") -- Backup of a single line...
-- If a line contains \entry, use counter mal +1...
malvalue=string.find(oneline,"\\entry")
if malvalue~=nil then
mal=mal+1
saved[mal]={}
-- initial setting...
saved[mal][1]="" -- In general, there is no need for namehash to be initialized, it is always there, but just to be sure...
saved[mal][2]=""
saved[mal][3]=""
saved[mal][4]=""
--print(oneline)
end
-- Search for these items in a line...
maltran={"namehash", "year", "month", "day"}
for k,v in pairs(maltran) do
searchme=".-{"..v.."}{(.-)}"
malvalue=string.find(oneline,searchme) --,"%1"
--print("MY LINE: "..oneline)
if malvalue~=nil then
--print(malvalue)
value=string.gsub(oneline,searchme,"%1")
--print(value)
saved[mal][k]=value -- Add their TeX value to my storage...
end --of if malvalue
end --of for k,v
end --of for oneline
--print(mal)
-- A creation of long hash...
for k=1,#saved do
saved[k][5]=saved[k][1]..saved[k][2]..saved[k][3]..saved[k][4]
saved[k][6]=0 -- the default value is zero, comment out that extrayear
--print(saved[k][5])
end
-- The comparison of two citations...
maltemp=1
for k=1,#saved-1 do
if saved[k][5]==saved[k+1][5] then
--print("they are equal") -- 1 2, 2 3, 3 4, ...
saved[k][6]=maltemp
maltemp=maltemp+1
saved[k+1][6]=maltemp
else
--print("they are not the same") -- Don't change anything...
maltemp=1 -- just set counter to one
end -- of if saved
end --of for k
-- For checking purposes only: list me the values...
-- for k=1,#saved do
-- print(saved[k][6])
-- end --of for k
-- Close those two files and open them again read and write mode in reverse...
myfile:close()
mybackup:close()
myfile=io.open(name,"w") -- From reading to writing...
mybackup=io.open(name.."-backup","r") -- From writing to reading...
content=mybackup:lines()
maltemp=0
for oneline in content do
malvalue=string.find(oneline,"\\entry") -- {extrayear} was here
malpercent=string.find(oneline,"%%")
if malvalue~=nil and malpercent==nil then -- Skip me if it is already updated (it occures only when there are multiple runs of mal-fixer.lua)...
maltemp=maltemp+1 -- n-th occurence in the file
if saved[maltemp][2]..saved[maltemp][3]..saved[maltemp][4]=="" then -- Neither year nor month nor day is stored in the bibliography entry, then do absolutly nothing...
else
if saved[maltemp][6]==0 then -- Does this date stand alone? Yes, it does.
-- This is an old version changing extrayear field...
-- oneline=string.gsub(oneline,"(.-)(\\.-)","%1%%%2") -- Comment out this line...
oneline=oneline.."\n \\field{userb}{}"
else -- No, it doesn't.
-- This is an old version...
-- oneline=string.gsub(oneline,"(.-year}{)(.-)(}.-)","%1"..tostring(saved[maltemp][6]).."%3%%%2") -- Change the value inside the TeX parameter...
oneline=oneline.."\n \\field{userb}{"..tostring(saved[maltemp][6]).."}"
end --of saved
end --of saved[maltemp] year+month+day
end --of if malvalue
myfile:write(oneline.."\n")
end --of for oneline (second cycle)
-- print(maltemp)
-- Close those two files again...
myfile:close()
mybackup:close()
-- Send a note to the terminal and exit the code...
local maltextbonus=""
if maltemp>1 then maltextbonus="s" end
print("Mal-fixer has done its assignment with "..tostring(mal).." item"..maltextbonus.."!")
--
答案3
我希望有人能给出更好的答案,但同时我只想指出,你可以在年份字段中放入更多内容,而 biber 不会抱怨:
@article{authorA1,
author={authorA},
title={blaa},
year={03.03.2014}
}
@article{authorA2,
author={authorA},
title={blab},
year={04.03.2014}
}
@article{authorA3,
author={authorA},
title={blac},
year={04.03.2014}
}
@article{authorA4,
author={authorA},
title={blad},
year={05.03.2014}
}