在法语和其他一些欧洲语言中,名字应该缩写,但要保留二元字母和三元字母。
- John 应缩写为 J。
- Clare 应缩写为 Cl。
- Charles 应缩写为 Ch。
- Christine 应缩写为 Chr。
- Philippe 应缩写为 Ph。
- ETC。
经典的解决方案是修改书目数据中的名字
查尔斯
到
{\relax查尔斯}
一个不错的宏由 Yves de Saint-Pern 编写,使用 Biber/Biblatex 中的正则表达式搜索和替换选项迭代您的 bib 文件并即时插入
在作者字段中\relax。
然而,最新的 Biber 打破了这种可能性。作者字段中带有 的 bib 条目\relax
将导致出现错误的 *.bbl 文件,其中包含不匹配的括号。请参阅这里和这里。
唯一的解决方法是使用 Biber 扩展名称格式,但是很麻烦:
- 这使得无法在 GUI 应用程序中编辑参考书目文件
- 这需要大量的手工工作
giveni
如果给定的名称以二元字母和三元字母列表开头,是否有可能修改 Biber 的首字母创建程序以创建正确的字段?
下面我列出了一个 MWE:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
% Extended name format
@book{Book1,
author = {family=Doe, given=Charles, given-i={Ch}},
title = {An Important Book},
publisher = {Publisher},
date = {2012},
}
@book{Book2,
author = {Dolittle, Charlotte},
title = {Another Important Book},
publisher = {Publisher},
date = {2014},
}
@book{Book3,
author = {Theodore Smith},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book4,
address = "Turnhout",
author = "Arnoux, Mathieu and Gazeau, Véronique and Demetz, Christine",
publisher = "Brepols",
shorttitle = "Les chanoines réguliers de la province de Rouen",
title = "{Des clercs au service de la réforme. Études et documents sur les chanoines réguliers de la province de Rouen}",
year = "2000"
}
\end{filecontents}
\usepackage[style=verbose,giveninits=true, backend=biber]{biblatex}
% Does not work anymore with the latest Biber
% \DeclareSourcemap{
% \maps[datatype=bibtex]{
% \map{
% \step[fieldsource=author,
% match={Charles},
% replace=\regexp{\{\\relax \x20Ch\}arles}]
% }
% }
% }
\addbibresource{\jobname.bib}
\begin{document}
\cite{Book1}
\cite{Book2}
\cite{Book3}
\cite{Book4}
\end{document}
答案1
如果您可以接受始终以“家人、亲人”的形式输入姓名,我们可以使用扩展姓名格式实现自动化。
\makeatletter
\def\do#1{%
\ifcsundef{blx@csv@datamodel@names}
{\csdef{blx@csv@datamodel@names}{#1}}
{\csappto{blx@csv@datamodel@names}{,#1}}}
\dolistcsloop{blx@datamodel@names}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map[foreach=\blx@csv@datamodel@names]{
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(\A|\s+and\s+)([a-z'\s]+)?\s*(.+?)\,\s+(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w)(.+?)(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$3, prefix=$2, given=$4$5, given-i=\{$4\}}]
}
}
}
\makeatother
使用正则表达式拆分首字母并将名称传递给扩展名称格式。现在,所有已知名称字段都会自动执行此操作。正则表达式改编自使用 Biblatex 在参考书目中添加两个或三个字母的首字母。
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
% Extended name format
@book{Book1,
author = {Doe, Charles and Potter, William},
title = {An Important Book},
publisher = {Publisher},
date = {2012},
}
@book{Book2,
author = {Dolittle, Charlotte},
title = {Another Important Book},
publisher = {Publisher},
date = {2014},
}
@book{Book3,
author = {Smith, Theodore},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book4,
address = "Turnhout",
author = "Arnoux, Mathieu and Gazeau, Véronique and Demetz, Christine",
publisher = "Brepols",
shorttitle = "Les chanoines réguliers de la province de Rouen",
title = "{Des clercs au service de la réforme. Études et documents sur les chanoines réguliers de la province de Rouen}",
year = "2000"
}
\end{filecontents}
\usepackage[style=verbose,giveninits=true, backend=biber]{biblatex}
\makeatletter
\def\do#1{%
\ifcsundef{blx@csv@datamodel@names}
{\csdef{blx@csv@datamodel@names}{#1}}
{\csappto{blx@csv@datamodel@names}{,#1}}}
\dolistcsloop{blx@datamodel@names}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map[foreach=\blx@csv@datamodel@names]{
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(\A|\s+and\s+)([a-z'\s]+)?\s*(.+?)\,\s+(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w)(.+?)(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$3, prefix=$2, given=$4$5, given-i=\{$4\}}]
}
}
}
\makeatother
\addbibresource{\jobname.bib}
\begin{document}
\cite{Book1}
\cite{Book2}
\cite{Book3}
\cite{Book4}
\end{document}
答案2
这是基于@moewe的解决方案的另一次尝试。它应该可以修复评论中发现的一些问题。
它没有解决重音字母的问题。我不知道为什么它们没有被正确地解析到字段given-i
中[在下面的编辑中修复]。
平均能量损失
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{Book1,
author = {Savigny, Friedrich Carl von},
title = {An Important Book},
publisher = {Publisher},
date = {2012},
}
@book{Book2,
author = {de La Vaissière, Claude-Henri},
title = {Another Important Book},
publisher = {Publisher},
date = {2014},
}
@book{Book3,
author = {Durand, Jean-Philippe},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book4,
author = {de La Boétie, Étienne},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book5,
author = {Doe, Charles-Édouard},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book6,
author = {Dolittle, Étienne-Marie},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
\end{filecontents}
\usepackage[style=verbose,giveninits=true, backend=biber]{biblatex}
\addbibresource{\jobname.bib}
\makeatletter
\def\do#1{%
\ifcsundef{blx@csv@datamodel@names}
{\csdef{blx@csv@datamodel@names}{#1}}
{\csappto{blx@csv@datamodel@names}{,#1}}}
\dolistcsloop{blx@datamodel@names}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map[foreach=\blx@csv@datamodel@names]{
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(\A|\s+and\s+)([a-z'\s]+)?\s*(.+?)\,\s+(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w(?=\w+-))([\w\s]+)(?:(-)(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w)([\w\s]+))?(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$3, prefix=$2, given=$4$5$6$7$8, given-i=\{$4$6$7\}}]
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(prefix=\,)},
replace=\regexp{}]
}
}
}
\makeatother
\begin{document}
Friedrich Carl von Savigny:\par
\cite{Book1}\medskip
Claude-Henri de La Vaissière:\par
\cite{Book2}\medskip
Jean-Philippe Durand:\par
\cite{Book3}\medskip
Étienne de La Boétie:\par
\cite{Book4}\medskip
Charles-Édouard Doe:\par
\cite{Book5}\medskip
Étienne-Marie Dolittle:\par
\cite{Book6}
\end{document}
从上面的输出可以看出:
- 带有部分的名称
von
正常工作(不支持Jr
部分)。 - 当一个人几个名字,只有第一个字母会被缩写(当一个名字使用多个首字母时,这是常见的做法)。
- 当一个人有合成名称,包括连字符,名称的两个部分均应正确缩写。
并且,作为[现已解决]问题重音字母,我使用的正则表达式试图尽量减少使用扩展名称格式的情况,以保留名称(和重音字母)的本机解析。目前,这意味着:
- 以重音字母开头的一个或多个名字将保留
- 组合姓名中的重音首字母将转换为非重音版本,如上例所示。
以下是详细代码,主要受到@moewe 的启发:
\def\do#1{%
\ifcsundef{blx@csv@datamodel@names}
{\csdef{blx@csv@datamodel@names}{#1}}
{\csappto{blx@csv@datamodel@names}{,#1}}}
\dolistcsloop{blx@datamodel@names}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map[foreach=\blx@csv@datamodel@names]{
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(\A|\s+and\s+)([a-z'\s]+)?\s*(.+?)\,\s+(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w(?=\w+-))([\w\s]+)(?:(-)(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w)([\w\s]+))?(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$3, prefix=$2, given=$4$5$6$7$8, given-i=\{$4$6$7\}}]
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(prefix=\,)},
replace=\regexp{}]
}
}
}
将其剥离,以防其他人想要玩弄正则表达式:
(\A|\s+and\s+)
:查找名称边界(“and”是分隔符)。匹配$1
。([a-z'\s]+)?
:查找von
只有小写字母时我们才感兴趣的部分(因为它会影响排序)。匹配$2
。\s*(.+?)\,\s+
:查找姓氏,后跟逗号。匹配$3
。(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w(?=\w+-))
:查找应用于名字中的首字母的字符串,或者取第一个字母 (\w
),但前提是名字是复合的(向前查找\w+-
,IE字母后跟连字符)。这样我们就可以从测试中排除一些带重音符号的首字母,从而保留它们。匹配$4
。([\w\s]+)
:查找名字的其余部分,包括任何后续名字。匹配$5
。(?:(-)(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|\w)([\w\s]+))?
:如果名称是复合名称,则重复最后两个步骤,但先查找起始连字符(匹配$6
),然后查找初始字符串或字母(匹配$7
,此处无需向前查找),然后查找名字的其余部分(匹配$8
)。(?=\Z|\s+and\s+)
:提前查看名称边界 = 结束。
此外,biber
当给出一个空von
部分时,会发出警告。因此,我们需要第二步来查找prefix=\,
并清除它。
编辑:在下面的评论中,@andc 发现了上述代码中的一个错误,虽然我没有时间仔细调查,但我有一个没有这个错误的较新版本的代码。作为奖励,此编辑还解决了先前的首字母重音问题。
以下是代码:
\def\do#1{%
\ifcsundef{blx@csv@datamodel@names}
{\csdef{blx@csv@datamodel@names}{#1}}
{\csappto{blx@csv@datamodel@names}{,#1}}}
\dolistcsloop{blx@datamodel@names}
\map[foreach=\blx@csv@datamodel@names,overwrite=true]{%
\step[fieldsource=\regexp{$MAPLOOP},%
match=\regexp{(\A|\s+and\s+)([a-z'\s]+)?\s*(.+?)\,\s+(Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|(?:À|Â|Ä|Ç|É|È|Ê|Ë|Î|Ï|Ô|Ö|Ù|Û|Ü|Ÿ|Æ|Œ)|\w)(.+?)(?:(\-(?:Chr?|Th|Ph|[B-DF-HJ-NP-TV-XZ](?:l|r)|(?:À|Â|Ä|Ç|É|È|Ê|Ë|Î|Ï|Ô|Ö|Ù|Û|Ü|Ÿ|Æ|Œ)|\w))(.+?))?(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$3, prefix=$2\\relax, given=$4$5$6$7, given-i=\{$4$6\}}]
\step[fieldsource=\regexp{$MAPLOOP},
match=\regexp{(prefix=\,)},
replace=\regexp{}]
}
答案3
我稍微修改了上述答案,以适用于作者和编辑以及 Philippe 的缩写。
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@book{Book1,
author = {Doe, Charles and Potter, William},
title = {An Important Book},
publisher = {Publisher},
date = {2012},
}
@book{Book2,
author = {Dolittle, Charlotte},
title = {Another Important Book},
publisher = {Publisher},
date = {2014},
}
@book{Book3,
author = {Smith, Philippe},
title = {A very Important Book},
publisher = {Publisher},
date = {2016},
}
@book{Book4,
address = "Turnhout",
editor = "Arnoux, Theodore and Gazeau, Véronique and Demetz, Christine",
publisher = "Brepols",
shorttitle = "Les chanoines réguliers de la province de Rouen",
title = "{Des clercs au service de la réforme. Études et documents sur les chanoines réguliers de la province de Rouen}",
year = "2000"
}
\end{filecontents}
\usepackage[style=verbose,giveninits=true, backend=biber]{biblatex}
\DeclareSourcemap{
\maps[datatype=bibtex]{
\map{
\step[fieldsource=author,
match=\regexp{(\A|\s+and\s+)(.+?)\,\s+(Chr?|Th|Ph|\w)(.+?)(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$2, given=$3$4, given-i=\{$3\}}]
\step[fieldsource=editor,
match=\regexp{(\A|\s+and\s+)(.+?)\,\s+(Chr?|Th|Ph|\w)(.+?)(?=\Z|\s+and\s+)},
replace=\regexp{$1 family=$2, given=$3$4, given-i=\{$3\}}]
}
}
}
\addbibresource{\jobname.bib}
\begin{document}
\cite{Book1}
\cite{Book2}
\cite{Book3}
\cite{Book4}
\end{document}