我(错误地)使用 biblatex 将我的一位植物爱好者朋友的学位和经验视为类型的 bib 条目@MISC
。
事实证明,我的朋友还没有完成他的博士学位。他希望在他的学位列表中传达这一点,方法是使用由 产生的优雅长破折号,---
并将其附加到year
bib 条目字段中他正在攻读的学位的起始年份。这似乎显示得相当好。
问题是,列表排序不正确,事实上 biber 发出了以下警告信息:
WARN - year field '2015---' in entry 'PhD' is not an integer - this will probably not sort properly.
我准备了以下 mwe 来演示这个问题:
\NeedsTeXFormat{LaTeX2e}
\documentclass[12pt]{article}
\usepackage[backend=biber,%
isbn=false,%
style=numeric,%
sorting=ydnt,%
giveninits=true,% initials of first names
maxbibnames=20,%
defernumbers,%
labeldateparts,% for academic cv
locallabelwidth% for academic cv
]{biblatex}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@Misc{BSc,
title = {B.Sc. in Observing the Natural World},
year = {2010},
note = {The University, Place},
}
@Misc{PhD,
title = {Ph.D. candidate, Botany and Plant Science},
year = {2015---},
note = {The Other University, The Other Place},
}
@Misc{MSc,
title = {M.Sc. in Epidemiology},
year = {2012},
note = {The University, Place},
}
\end{filecontents}
\begin{filecontents}{cvsectionnum.tex}
% define a bibenvironment for an numbered bib entry
\defbibenvironment{bibenvcvsectionnum}%
{\list%
{\printtext[labelnumberwidth]{%
\printfield{labelprefix}%
\printfield{labelnumber}}}%
{\setlength{\leftmargin}{\bibhang}%
\setlength{\itemsep}{\bibitemsep}%
\setlength{\parsep}{\bibparsep}}}%
{\endlist}%
{\item}%
% cvsectionnum
\newcommand\cvsectionnum[3]{%
\section*{#1}%
\begin{refsection}[#2]%
\nocite{*}%
\printbibliography[heading=none,env=bibenvcvsectionnum,#3]%
\end{refsection}%
}%
\end{filecontents}
\begin{filecontents}{reverse_order_bib_entry_numbering.tex}
\AtDataInput{%
\csnumgdef{entrycount:\therefsection}{%
\csuse{entrycount:\therefsection}+1}}%
%
\DeclareFieldFormat{labelnumber}{\mkbibdesc{#1}}%
\newrobustcmd*{\mkbibdesc}[1]{%
\number\numexpr\csuse{entrycount:\therefsection}+1-#1\relax}%
\end{filecontents}
\addbibresource{\jobname.bib}%
% declare section names
\def\sectiona{Publications}%
% definition of `cvsectionnum'
\input{cvsectionnum.tex}
% reverse order numbering
\input{reverse_order_bib_entry_numbering.tex}
\begin{document}
% Publications
\cvsectionnum{\sectiona}{\jobname.bib}{}%
\end{document}
我认为这不是什么大问题,因为我和我的朋友明显违反了年份字段应该是整数的事实;而且我们给它传递了一个字符串(2015---
)。
话虽如此,也许社区中的某个人对如何解决问题有一些聪明的想法。
输出结果如下:
正在进行的活动,即博士学位,应该从上到下首先出现,并且理想情况下应该带有标签 3。
实际上,这是我的朋友喜欢的表示教育项目的方式:
\NeedsTeXFormat{LaTeX2e}
\documentclass[12pt]{article}
\usepackage[backend=biber,%
isbn=false,%
style=numeric,%
sorting=ydnt,%
giveninits=true,% initials of first names
maxbibnames=20,%
defernumbers,%
labeldateparts,% for academic cv
locallabelwidth% for academic cv
]{biblatex}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@Misc{BSc,
title = {B.Sc. in Observing the Natural World},
year = {2010},
note = {The University, Place},
}
@Misc{PhD,
title = {Ph.D. candidate, Botany and Plant Science},
year = {2015---},
note = {The Other University, The Other Place},
}
@Misc{MSc,
title = {M.Sc. in Epidemiology},
year = {2012},
note = {The University, Place},
}
\end{filecontents}
\begin{filecontents}{cvsectionyearlabelkeywords.tex}
% cvsectionyearlabelkeywords
\newcommand\cvsectionyearlabelkeywords[3]
{%
\section*{#1}%
%\changedateformat{label}{long}% just the year
\begin{refsection}[#2]%
\nocite{*}%
\printbibliography[heading=none, env=bibenvcvsectionyearlabel,#3]%
\end{refsection}%
}%
% define a custom bib environment
\defbibenvironment{bibenvcvsectionyearlabel}
{\list
{\printtext{\printlabeldate}}%{\printtext[parens]{\printlabeldate}}
{\setlength{\labelwidth}{\labeldatewidth}%
\setlength{\leftmargin}{\labelwidth}%
\setlength{\labelsep}{\biblabelsep}%
\addtolength{\leftmargin}{\labelsep}%
\setlength{\itemsep}{\bibitemsep}%
\setlength{\parsep}{\bibparsep}}%
\renewcommand*{\makelabel}[1]{##1\hss}}
{\endlist}
{\item}
\renewbibmacro*{date}{%
\ifboolexpr{
test {\iflabeldateisdate}
and
not test {\ifdateshavedifferentprecision{label}{}}
}
{}
{\printdate}}
\renewbibmacro*{issue+date}{%
\ifboolexpr{
test {\iflabeldateisdate}
and
not test {\ifdateshavedifferentprecision{label}{}}
and
test {\iffieldundef{issue}}
}
{}
{\printtext{%{\printtext[parens]{
\printfield{issue}%
\setunit*{\addspace}%
\printdate}}%
\newunit}
\makeatletter
\newlength{\labeldatewidth}
\newlength{\locallabeldatewidth}
\preto\blx@bbl@labeldate
{\blx@getlabeldata
\blx@setlabwidth{\labeldatewidth}{\printtext{\printlabeldate}}}%\blx@setlabwidth{\labeldatewidth}{\printtext[parens]{\printlabeldate}}}
{}{}
\apptocmd\blx@labelwidth@resetlocal{\locallabeldatewidth0pt\relax}{}{}
\apptocmd\blx@labelwidth@settolocal{\labeldatewidth\locallabeldatewidth\relax}{}{}
\def\blx@lengthitem#1{%
\blx@ifdata{#1}
{\begingroup
\blx@getdata{#1}%
\blx@bibcheck
\iftoggle{blx@skipentry}{}{%
\iftoggle{blx@labelnumber}
{\blx@bbl@locallabelnumberwidth}
{}%
\iftoggle{blx@labelalpha}
{\blx@bbl@locallabelalphawidth}
{}%
\nottoggle{blx@skipbiblist}
{\blx@bbl@locallabelfields}
{}
\blx@setlabwidth{\locallabeldatewidth}{\printtext{\printlabeldate}}}%\blx@setlabwidth{\locallabeldatewidth}{\printtext[parens]{\printlabeldate}}}
\endgroup}
{}}
\newrobustcmd*{\changedateformat}[2]{%
\csdef{blx@dateformat@#1date}{#2}%
\protected\csdef{blx@imc@print#1date}{\csuse{mkdaterange#2}{#1}}%
\protected\csdef{blx@imc@print#1dateextra}{\csuse{mkdaterange#2extra}{#1}}}
\makeatletter
\end{filecontents}
\begin{filecontents}{reverse_order_bib_entry_numbering.tex}
\AtDataInput{%
\csnumgdef{entrycount:\therefsection}{%
\csuse{entrycount:\therefsection}+1}}%
%
\DeclareFieldFormat{labelnumber}{\mkbibdesc{#1}}%
\newrobustcmd*{\mkbibdesc}[1]{%
\number\numexpr\csuse{entrycount:\therefsection}+1-#1\relax}%
\end{filecontents}
\addbibresource{\jobname.bib}%
% declare section names
\def\sectiona{Education}%
% definition of `cvsectionnum'
\input{cvsectionyearlabelkeywords.tex}
% reverse order numbering
\input{reverse_order_bib_entry_numbering.tex}
\begin{document}
% Education
\cvsectionyearlabelkeywords{\sectiona}{\jobname.bib}{}%
\end{document}
看起来像:
再次,顺序被破坏并且不能有效地传达我的朋友的折衷形成。
答案1
至少有两种可能的解决方案。
使用date
和 ISO 输入
虽然该year
字段仅接受整数年份,但(现在首选)date
字段接受一系列 ISO 8601 日期格式。除其他外,date
还接受日期范围,甚至是开放式的日期范围。在 ISO 8601 日期范围中,使用/
作为分隔符,因为-
被视为年、月和日之间的分隔符,因此 ISO 8601 输入将是
@Misc{PhD,
title = {Ph.D. candidate, Botany and Plant Science},
date = {2015/},
note = {The Other University, The Other Place},
}
使用sortyear
如果你有一个非整数year
字段,你仍然可以通过添加整数值来让 Biber/BibTeX 有机会正确排序sortyear
,例如
@Misc{PhD,
title = {Ph.D. candidate, Botany and Plant Science},
year = {2015---},
sortyear = {2015},
note = {The Other University, The Other Place},
}
MWE 使用date
。默认情况下,范围分隔符是 en-dash 而不是 em-dash,但您可以使用 在年份后获得 em-dash \renewrobustcmd*{\bibdaterangesep}{\textemdash}
。
\NeedsTeXFormat{LaTeX2e}
\documentclass[12pt]{article}
\usepackage[backend=biber,%
isbn=false,%
style=numeric,%
sorting=ydnt,%
giveninits=true,% initials of first names
maxbibnames=20,%
defernumbers,%
labeldateparts,% for academic cv
locallabelwidth% for academic cv
]{biblatex}
\begin{filecontents}{\jobname.bib}
@Misc{BSc,
title = {B.Sc. in Observing the Natural World},
year = {2010},
note = {The University, Place},
}
@Misc{PhD,
title = {Ph.D. candidate, Botany and Plant Science},
date = {2015/},
note = {The Other University, The Other Place},
}
@Misc{MSc,
title = {M.Sc. in Epidemiology},
year = {2012},
note = {The University, Place},
}
\end{filecontents}
\begin{filecontents}{cvsectionyearlabelkeywords.tex}
% cvsectionyearlabelkeywords
\newcommand\cvsectionyearlabelkeywords[3]
{%
\section*{#1}%
%\changedateformat{label}{long}% just the year
\begin{refsection}[#2]%
\nocite{*}%
\printbibliography[heading=none, env=bibenvcvsectionyearlabel,#3]%
\end{refsection}%
}%
% define a custom bib environment
\defbibenvironment{bibenvcvsectionyearlabel}
{\list
{\printtext{\printlabeldate}}%{\printtext[parens]{\printlabeldate}}
{\setlength{\labelwidth}{\labeldatewidth}%
\setlength{\leftmargin}{\labelwidth}%
\setlength{\labelsep}{\biblabelsep}%
\addtolength{\leftmargin}{\labelsep}%
\setlength{\itemsep}{\bibitemsep}%
\setlength{\parsep}{\bibparsep}}%
\renewcommand*{\makelabel}[1]{##1\hss}}
{\endlist}
{\item}
\renewrobustcmd*{\bibdaterangesep}{\textemdash}
\renewbibmacro*{date}{%
\ifboolexpr{
test {\iflabeldateisdate}
and
not test {\ifdateshavedifferentprecision{label}{}}
}
{}
{\printdate}}
\renewbibmacro*{issue+date}{%
\ifboolexpr{
test {\iflabeldateisdate}
and
not test {\ifdateshavedifferentprecision{label}{}}
and
test {\iffieldundef{issue}}
}
{}
{\printtext{%{\printtext[parens]{
\printfield{issue}%
\setunit*{\addspace}%
\printdate}}%
\newunit}
\makeatletter
\newlength{\labeldatewidth}
\newlength{\locallabeldatewidth}
\preto\blx@bbl@labeldate
{\blx@getlabeldata
\blx@setlabwidth{\labeldatewidth}{\printtext{\printlabeldate}}}%\blx@setlabwidth{\labeldatewidth}{\printtext[parens]{\printlabeldate}}}
{}{}
\apptocmd\blx@labelwidth@resetlocal{\locallabeldatewidth0pt\relax}{}{}
\apptocmd\blx@labelwidth@settolocal{\labeldatewidth\locallabeldatewidth\relax}{}{}
\def\blx@lengthitem#1{%
\blx@ifdata{#1}
{\begingroup
\blx@getdata{#1}%
\blx@bibcheck
\iftoggle{blx@skipentry}{}{%
\iftoggle{blx@labelnumber}
{\blx@bbl@locallabelnumberwidth}
{}%
\iftoggle{blx@labelalpha}
{\blx@bbl@locallabelalphawidth}
{}%
\nottoggle{blx@skipbiblist}
{\blx@bbl@locallabelfields}
{}
\blx@setlabwidth{\locallabeldatewidth}{\printtext{\printlabeldate}}}%\blx@setlabwidth{\locallabeldatewidth}{\printtext[parens]{\printlabeldate}}}
\endgroup}
{}}
\newrobustcmd*{\changedateformat}[2]{%
\csdef{blx@dateformat@#1date}{#2}%
\protected\csdef{blx@imc@print#1date}{\csuse{mkdaterange#2}{#1}}%
\protected\csdef{blx@imc@print#1dateextra}{\csuse{mkdaterange#2extra}{#1}}}
\makeatletter
\end{filecontents}
\begin{filecontents}{reverse_order_bib_entry_numbering.tex}
\AtDataInput{%
\csnumgdef{entrycount:\therefsection}{%
\csuse{entrycount:\therefsection}+1}}%
%
\DeclareFieldFormat{labelnumber}{\mkbibdesc{#1}}%
\newrobustcmd*{\mkbibdesc}[1]{%
\number\numexpr\csuse{entrycount:\therefsection}+1-#1\relax}%
\end{filecontents}
\addbibresource{\jobname.bib}%
\def\sectiona{Education}%
\input{cvsectionyearlabelkeywords.tex}
\input{reverse_order_bib_entry_numbering.tex}
\begin{document}
\cvsectionyearlabelkeywords{\sectiona}{\jobname.bib}{}%
\end{document}