如何在 biblatex DeclareFieldFormat 中使用 xstring 命令?

如何在 biblatex DeclareFieldFormat 中使用 xstring 命令?

我正在尝试调整biblatex书目。一个问题是带有字段的条目的呈现eprint。有时,我会遇到类似

  eprint         = "hep-ph/0207124",

有时它的

  eprint         = "0207124",
  primaryClass   = "hep-ph",

但有时课程以两种方式给出:

  eprint         = "hep-ph/0207124",
  primaryClass   = "hep-ph",

例如,我希望以“arXiv:hep-ph/0207124”之类的格式一致地呈现所有内容。为此,我尝试自定义\DeclareFieldFormat{eprint:arxiv}。我的问题是我无法在中正确使用或之xstring类的命令。如果我尝试在中找到,它就不起作用。\IfSubStr\StrDel\DeclareFieldFormatprimaryClasseprint

我查了一下。如果#1hep-ph/0207124,那么

\StrDel{#1}{\thefield{eprintclass}}

不起作用。它找不到字符串。我想我需要以\thefield某种方式进行扩展。即便如此,直接替换字符串也不起作用:

\StrDel{#1}{hep-ph}

但如果我使用0\string h(而不是h)作为参数,它就会部分起作用。我相信这与参数的 catcode 有关。我尝试了很多\detokenize、、,但如果没有系统的方法\expandafter\expandarg我就无法让它工作。

那么如何在 biblatex 的字段格式中正确使用字符串操作命令?

(不完全)最小(不完全)工作示例如下:

\documentclass{article}

\usepackage{filecontents}
\begin{filecontents}{\jobname.bib}
@article{Witten:2002ei,
      author         = "Witten, Edward",
      title          = "{Quest for unification}",
      pages          = "604-610",
      year           = "2002",
      eprint         = "hep-ph/0207124",
      archivePrefix  = "arXiv",
      primaryClass   = "hep-ph",
      SLACcitation   = "%%CITATION = HEP-PH/0207124;%%",
}
\end{filecontents}

\usepackage[style=numeric,sorting=none]{biblatex}
\addbibresource{\jobname.bib}

\usepackage{xstring}
\makeatletter

\DeclareFieldFormat{eprint:arxiv}{%
  arXiv\addcolon\space%
  \iffieldundef{eprintclass}%
    {#1}%
    {%
    eprint = #1 \par
    class = \thefield{eprintclass} \par
    number = \StrDel{#1}{\thefield{eprintclass}} \par
    removing `0' = \StrDel{#1}{0} \par%
    removing `h' = \StrDel{#1}{h} \par%
    removing `\textbackslash string h' = \StrDel{#1}{\string h} \par%
    }%
}

\makeatother

\begin{document}

\cite{Witten:2002ei}

\printbibliography
\end{document}

答案1

诀窍是扩展该字段,然后将其转换为“其他”类别代码使用在这里找到的 hack

\edef\mytemporary{\thefield{eprintclass}}
\edef\myeprintclass{\expandafter\strip@prefix\meaning\mytemporary}
% then this works as expected:
\StrDel{#1}{\myeprintclass}

仅当字段尚未以 + 开头时,才会附加primaryClass+ :/eprint

\makeatletter

\newbibmacro{eprint+arxiv}[1]{%
  arXiv\addcolon\space%
  \iffieldundef{eprintclass}%
    {#1}%
    {%
    \edef\mytemporary{\thefield{eprintclass}}%
    \edef\myeprintclass{\expandafter\strip@prefix\meaning\mytemporary}%
    \IfBeginWith{#1}{\myeprintclass/}%
      {#1}%
      {\myeprintclass/#1}%
    }%
}

\DeclareFieldFormat{eprint:arxiv}{%
  \ifhyperref%
    {\href{http://arxiv.org/\abx@arxivpath/#1}{%
      {\usebibmacro{eprint+arxiv}{#1}}%
    }}%
    {\usebibmacro{eprint+arxiv}{#1}}%
}

\makeatother

答案2

使用 biber 执行此操作更简洁,\DeclareSourcemap这样您就不必使自己的风格复杂化。您需要使用 biber 1.9+biblatex 2.9(均位于 SourceForge 上的开发文件夹中)。将其放入您的序言中:

\DeclareSourcemap{
  \maps[datatype=bibtex]{
    \map[overwrite=true]{
       \step[fieldsource=primaryclass, match=\regexp{(.+)}, final]
       \step[fieldsource=eprint, notmatch=\regexp{\A$1/}, final]
       \step[fieldsource=eprint]
       \step[fieldset=primaryclass, fieldvalue=/, append]
       \step[fieldset=primaryclass, origfieldval, append]
       \step[fieldsource=primaryclass, fieldtarget=eprint]
    }
    \map[overwrite=true]{
       \step[fieldset=primaryclass, null]
    }
  }
}

相关内容