biblatex:自动缩写年份范围

biblatex:自动缩写年份范围

为了保持一致性,我需要缩写全部我的文档中的数字范围。

虽然 biblatex可以轻松缩短页面范围年份范围的等效命令会中断编译Argument of \@secondoftwo has an extra }

\documentclass{article}
\usepackage{filecontents}

\begin{filecontents*}{mylibrary.bib}
@book{somebook1769,
    Address = {Place},
    Author = {Name, Given},
    Title = {Some title of this publication},
    Date = {1769/1783}}
}
\end{filecontents*}

\usepackage[style=authoryear,backend=biber]{biblatex}
\usepackage{csquotes}
\addbibresource{mylibrary.bib}

\DeclareFieldFormat{postnote}{\mkcomprange[{\mkpageprefix[pagination]}]{#1}}
\DeclareFieldFormat{pages}{\mkcomprange{#1}}

%%doesn't work:
%\DeclareFieldFormat{date}{\mkcomprange{#1}}


%%works (just for comparison)
%\DeclareFieldFormat{date}{\textbf{#1}}


\begin{document}
“some quote” from \cite[1348--1368]{somebook1769}

\printbibliography
\end{document}

(我尝试使用

    Year = {1769--83}}

哪个看起来正确,但 biblatex 警告

   WARN - year field '1769--83' in entry 'somebook1769' is not an integer - this will probably not sort properly.

并且书目中同一作者的几部作品的出版顺序确实不正确。

答案1

大多数函数都已存在,因此我们只需将它们拼凑在一起即可。遗憾的是,biblatex由于支持许多 EDTF/ISO 8601 功能,日期处理代码有点复杂。

默认语言使用的美国日期格式english需要特殊处理。因此,完成此操作所需的行数实际上增加了一倍。

\documentclass[american]{article}
\usepackage{babel}
\usepackage{csquotes}
\usepackage[style=authoryear, backend=biber]{biblatex}

\DeclareFieldFormat{postnote}{\mkcomprange[{\mkpageprefix[pagination]}]{#1}}
\DeclareFieldFormat{pages}{\mkcomprange{#1}}

\makeatletter
\newcommand*{\ifcompyear}[1]{%
  \ifboolexpr{        test {\iffieldundef{#1month}}
              and     test {\iffieldundef{#1endmonth}}
              and not test {\iffieldundef{#1endyear}}
              and not test {\iffieldequalstr{#1endyear}{}}
              and     test {\iffieldsequal{#1dateera}{#1enddateera}}
              and test     {\iffieldint{#1year}}
              and test     {\iffieldint{#1endyear}}}}

\newrobustcmd*{\compyear}[1]{%
  \begingroup
  \edef\blx@compyear@tempa{\thefield{#1year}-\thefield{#1endyear}}%
  \expandafter\mkcomprange\expandafter{\blx@compyear@tempa}%
  \endgroup}

\renewrobustcmd*{\mkdaterangetrunc}[2]{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         % Such a season component can only come from an ISO8601 season which replaces
         % a normal month so if it exists, we know that a normal date print is ruled out
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
              {\iffieldsequal{#2month}{#2endmonth}
                 {\csuse{mkbibdate#1}{}{}{#2day}}
                 {\csuse{mkbibdate#1}{}{#2month}{#2day}}}
              {\ifcompyear{#2}
                 {}
                 {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                  \iffieldsequal{#2dateera}{#2enddateera}{}
                    {\dateeraprint{#2year}}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \iffieldsequal{#2dateera}{#2enddateera}{}
                {\dateeraprint{#2year}}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {}
           {\iffieldequalstr{#2endyear}{}
              {\mbox{\bibdaterangesep}}
              {\ifcompyear{#2}
                 {\dateeraprintpre{#2endyear}%
                  \compyear{#2}%
                  \dateeraprint{#2endyear}}
                 {\bibdaterangesep
                  \enddatecircaprint
                  \iffieldundef{#2season}
                    {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}
                    {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
                  \enddateuncertainprint
                  \dateeraprint{#2endyear}}}}}}%
  \endgroup}

\renewrobustcmd*{\mkdaterangetruncextra}[2]{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         % Such a season component can only come from an ISO8601 season which replaces
         % a normal month so if it exists, we know that a normal date print is ruled out
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
              {\iffieldsequal{#2month}{#2endmonth}
                 {\csuse{mkbibdate#1}{}{}{#2day}}
                 {\csuse{mkbibdate#1}{}{#2month}{#2day}}}
              {\ifcompyear{#2}
                 {}
                 {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                  \iffieldsequal{#2dateera}{#2enddateera}{}
                    {\dateeraprint{#2year}}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \iffieldsequal{#2dateera}{#2enddateera}{}
                {\dateeraprint{#2year}}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {\printfield{extradate}}
           {\iffieldequalstr{#2endyear}{}
              {\printfield{extradate}%
               \printtext{\mbox{\bibdaterangesep}}}
              {\ifcompyear{#2}
                 {\dateeraprintpre{#2endyear}%
                  \compyear{#2}%
                  \printfield{extradate}%
                  \dateeraprint{#2endyear}}
                 {\printtext{%
                    \bibdaterangesep
                    \enddatecircaprint
                    \iffieldundef{#2season}
                      {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}
                      {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}}%
                    \printfield{extradate}%
                    \enddateuncertainprint
                    \dateeraprint{#2endyear}}}}}}%
  \endgroup}

\newrobustcmd*{\mkdaterangecompyear}[1]{%
  \blx@imc@clearfield{#1season}%
  \blx@imc@clearfield{#1month}%
  \blx@imc@clearfield{#1day}%
  \blx@imc@clearfield{#1hour}%
  \blx@imc@clearfield{#1minute}%
  \blx@imc@clearfield{#1second}%
  \blx@imc@clearfield{#1timezone}%
  \blx@imc@clearfield{#1endseason}%
  \blx@imc@clearfield{#1endmonth}%
  \blx@imc@clearfield{#1endday}%
  \blx@imc@clearfield{#1endhour}%
  \blx@imc@clearfield{#1endminute}%
  \blx@imc@clearfield{#1endsecond}%
  \blx@imc@clearfield{#1endtimezone}%
  \ifdateyearsequal{#1}{#1end}
    {\blx@imc@clearfield{#1endyear}}
    {}%
  \mkdaterangetrunc{short}{#1}}

\newrobustcmd*{\mkdaterangecompyearextra}[1]{%
  \blx@imc@clearfield{#1season}%
  \blx@imc@clearfield{#1month}%
  \blx@imc@clearfield{#1day}%
  \blx@imc@clearfield{#1hour}%
  \blx@imc@clearfield{#1minute}%
  \blx@imc@clearfield{#1second}%
  \blx@imc@clearfield{#1timezone}%
  \blx@imc@clearfield{#1endseason}%
  \blx@imc@clearfield{#1endmonth}%
  \blx@imc@clearfield{#1endday}%
  \blx@imc@clearfield{#1endhour}%
  \blx@imc@clearfield{#1endminute}%
  \blx@imc@clearfield{#1endsecond}%
  \blx@imc@clearfield{#1endtimezone}%
  \ifdateyearsequal{#1}{#1end}
    {\blx@imc@clearfield{#1endyear}}
    {}%
  \mkdaterangetruncextra{short}{#1}}

\DefineBibliographyExtras{english}{%
\protected\gdef\lbx@us@mkdaterangetrunc@long#1#2{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibdate#1}{}{#2month}{#2day}}
             {\ifcompyear{#2}
                {}
                {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                 \dateeraprint{#2year}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \dateeraprint{#2year}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {}
           {\iffieldequalstr{#2endyear}{}
             {\mbox{\bibdaterangesep}}
             {\ifcompyear{#2}
                {\dateeraprintpre{#2endyear}%
                 \compyear{#2}%
                 \dateeraprint{#2endyear}}
                {\bibdaterangesep
                 \enddatecircaprint
                 \iffieldundef{#2season}
                   {\ifdateyearsequal{#2}{#2end}
                     {\iffieldsequal{#2month}{#2endmonth}
                       {\csuse{mkbibdate#1}{#2endyear}{}{#2endday}}
                       {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}}
                     {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}}
                   {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
                 \enddateuncertainprint
                 \dateeraprint{#2endyear}}}}}}%
  \endgroup}%
\protected\gdef\lbx@us@mkdaterangetrunc@short#1#2{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibdate#1}{}{#2month}{#2day}}
             {\ifcompyear{#2}
                {}
                {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                 \dateeraprint{#2year}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \dateeraprint{#2year}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {}
           {\iffieldequalstr{#2endyear}{}
              {\mbox{\bibdaterangesep}}
              {\ifcompyear{#2}
                {\dateeraprintpre{#2endyear}%
                 \compyear{#2}%
                 \dateeraprint{#2endyear}}
                {\bibdaterangesep
                  \enddatecircaprint
                  \iffieldundef{#2season}
                    {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}
                    {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
                  \enddateuncertainprint
                  \dateeraprint{#2endyear}}}}}}%
  \endngroup}%
\protected\gdef\lbx@us@mkdaterangetruncextra@long#1#2{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibdate#1}{}{#2month}{#2day}}
             {\ifcompyear{#2}
                {}
                {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                 \dateeraprint{#2year}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \dateeraprint{#2year}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {\printfield{extradate}}
           {\iffieldequalstr{#2endyear}{}
              {\printfield{extradate}%
               \mbox{\bibdaterangesep}}
              {\ifcompyear{#2}
                {\dateeraprintpre{#2endyear}%
                 \compyear{#2}%
                 \printfield{extradate}%
                 \dateeraprint{#2endyear}}
                {\bibdaterangesep
                  \enddatecircaprint
                  \iffieldundef{#2season}
                    {\ifdateyearsequal{#2}{#2end}
                      {\iffieldsequal{#2month}{#2endmonth}
                         {\csuse{mkbibdate#1}{#2endyear}{}{#2endday}}
                         {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}}
                      {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}}
                    {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
                  \printfield{extradate}%
                  \enddateuncertainprint
                  \dateeraprint{#2endyear}}}}}}%
  \endgroup}%
\protected\gdef\lbx@us@mkdaterangetruncextra@short#1#2{%
  \begingroup
    \blx@metadateinfo{#2}%
    \iffieldundef{#2year}
      {\blx@nounit}
      {\printtext[#2date]{%
         \datecircaprint
         \iffieldundef{#2season}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibdate#1}{}{#2month}{#2day}}
             {\ifcompyear{#2}
                {}
                {\csuse{mkbibdate#1}{#2year}{#2month}{#2day}%
                 \dateeraprint{#2year}}}}
           {\ifdateyearsequal{#2}{#2end}
             {\csuse{mkbibseasondate#1}{}{#2season}}
             {\csuse{mkbibseasondate#1}{#2year}{#2season}%
              \dateeraprint{#2year}}}%
         \dateuncertainprint
         \iffieldundef{#2endyear}
           {\printfield{extradate}}
           {\iffieldequalstr{#2endyear}{}
              {\printfield{extradate}%
            \mbox{\bibdaterangesep}}
           {\ifcompyear{#2}
                {\dateeraprintpre{#2endyear}%
                 \compyear{#2}%
                 \printfield{extradate}%
                 \dateeraprint{#2endyear}}
                {\bibdaterangesep
               \enddatecircaprint
               \iffieldundef{#2season}
                 {\csuse{mkbibdate#1}{#2endyear}{#2endmonth}{#2endday}}
                 {\csuse{mkbibseasondate#1}{#2endyear}{#2endseason}}%
               \printfield{extradate}%
               \enddateuncertainprint
               \dateeraprint{#2endyear}}}}}}%
  \endgroup}%
}
\makeatother

\ExecuteBibliographyOptions{labeldate=compyear}


\usepackage{filecontents}
\begin{filecontents*}{\jobname.bib}
@book{somebook1769,
  address = {Place},
  author  = {Name, Given},
  title   = {Some title of this publication},
  date    = {1769/1783},
}
\end{filecontents*}
\addbibresource{\jobname.bib}

\begin{document}
\enquote{some quote} from \cite[1348--1368]{somebook1769}

\printbibliography
\end{document}

“1769–83”

相关内容