在自定义数据模型中修补 endyear 以实现正确排序

在自定义数据模型中修补 endyear 以实现正确排序

我正在创建一个自定义数据模型,类似于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放错了位置。

糟糕的测试3

我认为这是因为,尽管源映射的补丁不起作用。由于将为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 年。

相关内容