我正在创建一个自定义数据模型,类似于https://tex.stackexchange.com/a/175896/7561endyear
。但是当日期没有正确定义时,我无法对其进行排序date
。
我的设置
我想使用一个date
字段来保存一系列日期(我不确定是否有更好的方法)并根据这些范围对条目进行排序。但是,我希望能够执行以下操作:
- 保留开放范围(
1994/
)以默认为现在,即 1994 年至今 - 将同一年份的范围转换为单个 (
1994/1994
) 到 1994 年,而不是 1994-1994 - 使用简写来表示同一年份范围,而不是书写
1994/1994
,在日期字段中使用简单的 1994
排序
对于排序我调整了另一个例子,重要的部分(我认为)是这个
\sort[direction=descending]{
\field{sortyear}
\field{endyear}
\literal{9999}
}
\sort[direction=descending]{
\field{sortyear}
\field{year}
\literal{9999}
}
所以我把 sort by 放在了endyear
前面year
。因此,条目应该按结束年份排序,然后按起始年份重新排序,对吗?
数据
如果您测试下面的例子,您会发现条目test3
放错了位置。
我认为这是因为,尽管源映射的补丁不起作用。由于将为endyear
空,因此它将默认9999
在排序的文字部分中使用。
但是,如果将条目更改为
@test{test3,
title = {A. third},
date = {1994/1994},
}
那么该命令就会得到尊重。
问题
所以我认为问题在于这张地图
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=year]
\step[fieldset=endyear, origfieldval]
}
}
}
然而,biblatex
文档说它应该可以工作。
问题
那么,我该如何修复地图或重新设计解决方案以修补缺失部分endyears
并将其默认为。请注意,当传递year
空白时,它应该保持空白,因此我可以将其默认为“present”。endyear
完整代码
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@test{test1,
title = {Second},
date = {1994/2000},
}
@test{test2,
title = {This should be first},
date = {1994/},
}
@test{test3,
title = {A. third},
date = {1994},
}
@test{test4,
title = {B. fourth},
date = {1994/1994},
}
\end{filecontents}
\begin{filecontents}{test.dbx}
\DeclareDatamodelFields[type=field, datatype=literal]{title}
\DeclareDatamodelFields[type=field, datatype=datepart]{
year,%
endyear,%
month,%
endmonth%
}
\DeclareDatamodelFields[type=field,datatype=date]{
date%
}
\DeclareDatamodelEntryfields[cvmisc]{%
date,%
title%
}
\end{filecontents}
\usepackage[datamodel=test, backend=biber, sortcites, sorting=ymdtn]{biblatex}
\addbibresource{\jobname.bib}
\DeclareSortingScheme{ymdtn}{
\sort{
\field{presort}
}
\sort[final]{
\field{sortkey}
}
\sort[direction=descending]{
\field{sortyear}
\field{endyear}
\literal{9999}
}
\sort[direction=descending]{
\field{sortyear}
\field{year}
\literal{9999}
}
\sort[direction=descending]{
\field[padside=left,padwidth=2,padchar=0]{month}
\literal{99}
}
\sort[direction=descending]{
\field[padside=left,padwidth=2,padchar=0]{day}
\literal{99}
}
\sort{
\field{sorttitle}
}
\sort[direction=descending]{
\field[padside=left,padwidth=4,padchar=0]{volume}
\literal{9999}
}
\sort{
\name{sortname}
\name{author}
\name{editor}
\name{translator}
\field{sorttitle}
\field{title}
}
}
% Patch endyears that are not declared according to biblatex manual example
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=year]
\step[fieldset=endyear, origfieldval]
}
}
}
% The range date macro
\newbibmacro*{range-date}{%
\iffieldundef{year}
{}
{\printtext{%
% If the item is in the same year,
\iffieldsequal{year}{endyear}%
% compress
{\mkbibdateshort{}{month}{}}%
% else, print the date
{\mkbibdateshort{year}{month}{}}%
\iffieldundef{endyear}%
{}%
{% print the dash if a month range was given
\ifthenelse{\( \iffieldsequal{year}{endyear} \and \iffieldundef{month} \)}{}{\bibdatedash}%
% if a range is given but blank,
\iffieldequalstr{endyear}{}%
% default to "present"
{present}%
% else, print a range
{%
\mkbibdateshort{endyear}{endmonth}{}%
}%
}%
}%
}%
}
% Dummy driver for testing
\DeclareBibliographyDriver{test}{%
\usebibmacro{begentry}%
\printfield{title}%
\newunit%
\usebibmacro{range-date}%
\usebibmacro{finentry}%
}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
答案1
使用映射
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=date, match=\regexp{\A([0-9]{4}-[0-9]{2}-[0-9]{2})\Z}, replace=\regexp{$1/$1}]
\step[fieldsource=date, match=\regexp{\A([0-9]{4}-[0-9]{2})\Z}, replace=\regexp{$1/$1}]
\step[fieldsource=date, match=\regexp{\A([0-9]{4})\Z}, replace=\regexp{$1/$1}]
}
}
}
日期如date = {1994}
扩展到date = {1994/1994}
。由于现在date = {1994/}
给出endyear = {}
,一切都应该正常工作。
平均能量损失
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@test{test1,
title = {Second},
date = {1994/2000},
}
@test{test2,
title = {This should be first},
date = {1994/},
}
@test{test3,
title = {A. third},
date = {1994},
}
@test{test4,
title = {B. fourth},
date = {1994/1994},
}
\end{filecontents}
\begin{filecontents}{test.dbx}
\DeclareDatamodelFields[type=field, datatype=literal]{title}
\DeclareDatamodelFields[type=field,datatype=date]{
date%
}
\DeclareDatamodelEntryfields[cvmisc]{%
date,%
title%
}
\end{filecontents}
\usepackage[datamodel=test, backend=biber, sortcites, sorting=ymdtn]{biblatex}
\addbibresource{\jobname.bib}
\DeclareSortingScheme{ymdtn}{
\sort{
\field{presort}
}
\sort[final]{
\field{sortkey}
}
\sort[direction=descending]{
\field{sortyear}
\field{endyear}
\literal{9999}
}
\sort[direction=descending]{
\field{sortyear}
\field{year}
\literal{9999}
}
\sort[direction=descending]{
\field[padside=left,padwidth=2,padchar=0]{month}
\literal{99}
}
\sort[direction=descending]{
\field[padside=left,padwidth=2,padchar=0]{day}
\literal{99}
}
\sort{
\field{sorttitle}
}
\sort[direction=descending]{
\field[padside=left,padwidth=4,padchar=0]{volume}
\literal{9999}
}
\sort{
\name{sortname}
\name{author}
\name{editor}
\name{translator}
\field{sorttitle}
\field{title}
}
}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=date, match=\regexp{\A([0-9]{4}-[0-9]{2}-[0-9]{2})\Z}, replace=\regexp{$1/$1}]
\step[fieldsource=date, match=\regexp{\A([0-9]{4}-[0-9]{2})\Z}, replace=\regexp{$1/$1}]
\step[fieldsource=date, match=\regexp{\A([0-9]{4})\Z}, replace=\regexp{$1/$1}]
}
}
}
% The range date macro
\newbibmacro*{range-date}{%
\iffieldundef{year}
{}
{\printtext{%
% If the item is in the same year,
\iffieldsequal{year}{endyear}%
% compress
{\mkbibdateshort{}{month}{}}%
% else, print the date
{\mkbibdateshort{year}{month}{}}%
\iffieldundef{endyear}%
{}%
{% print the dash if a month range was given
\ifthenelse{\( \iffieldsequal{year}{endyear} \and \iffieldundef{month} \)}{}{\bibdatedash}%
% if a range is given but blank,
\iffieldequalstr{endyear}{}%
% default to "present"
{present}%
% else, print a range
{%
\mkbibdateshort{endyear}{endmonth}{}%
}%
}%
}%
}%
}
% Dummy driver for testing
\DeclareBibliographyDriver{test}{%
\usebibmacro{begentry}%
\printfield{title}%
\newunit%
\usebibmacro{range-date}%
\usebibmacro{finentry}%
}
\begin{document}
\nocite{*}
\printbibliography
\end{document}
[1]这应该是第一个。1994 年至今。
[2]第二。1994–2000 年。
[3]三分之一。1994 年。
[4]B.第四。1994 年。