使用 Biblatex 查找参考书目中的两个或三个字母的首字母(再次)

使用 Biblatex 查找参考书目中的两个或三个字母的首字母(再次)

在法语和其他一些欧洲语言中,名字应该缩写,但要保留二元字母和三元字母。

  • 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}

enter image description here

答案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}

enter image description here

答案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}

enter image description here

从上面的输出可以看出:

  • 带有部分的名称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}

enter image description here

相关内容