biblatex:如果 url 字符串尚未这样包装,则仅将其包装在 \url 中

biblatex:如果 url 字符串尚未这样包装,则仅将其包装在 \url 中

我正在使用定制的 BibLaTeX 书目样式,其中使用以下宏:\newbibmacro{archive}[1]{\\\textsc{Archived:}\ \url{#1}}

我使用它来格式化某些 URL,它是从其他宏中调用的,使用字符串(通常为"http://www.somesite.com")作为参数。这很好用。

然而,由于我无法控制的原因,有时我需要传递给宏的字符串已经是 形式"\url{http://www.somesite.com}"。这意味着我的宏随后会生成\\\textsc{Archived:}\ \url{\url{http://www.somesite.com}},这当然会导致由于嵌套 而导致的 latex 编译错误\url

所以,我的问题是:我怎样才能更改上述宏,以便它只包装其参数(#1\url如果它还没有这样包装的话?

编辑:MWE 澄清了我对 egreg 答案的问题

尽管我的原始宏在双重包装 URL 的情况下会导致编译问题,但它在我的 bbx 文件中的存在本身并不会破坏编译。例如,这可以很好地编译:

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents}{test.bbx}
\ProvidesFile{test.bbx}
\RequireBibliographyStyle{numeric-comp} %in turn that one requires standard.bbx
\newbibmacro{archive}[1]{\\\textsc{Archived:}\ \url{#1}}
\end{filecontents}

\usepackage[bibstyle=test]{biblatex}

\begin{document}
Blah blah
\end{document}

但是,当我将 egreg 的解决方案放入 bbx 文件中时(这是我想要的,因为这个宏是我自定义参考书目样式的一部分),它会导致编译错误(即使没有调用该宏)。因此,这确实不是编译:

\documentclass{article}

\usepackage{filecontents}

\begin{filecontents}{test.bbx}
\ProvidesFile{test.bbx}
\RequireBibliographyStyle{numeric-comp} %in turn that one requires standard.bbx
\makeatletter
\newbibmacro{archive}[1]{\\\textsc{Archived:} \test@URL#1\@nil}
\def\test@URL{\@ifnextchar\url\test@URL@i\test@URL@ii}
\def\test@URL@i#1\@nil{#1}
\def\test@URL@ii#1\@nil{\url{#1}}
\makeatother
\end{filecontents}

\usepackage[bibstyle=test]{biblatex}

\begin{document}
Blah blah
\end{document}

我猜是因为那些\makeatletter/other东西吧?我一直不太明白那是干什么用的 :-)

答案1

\makeatletter
\newbibmacro{archive}[1]{\\\textsc{Archived:} \test@URL#1\@nil}
\def\test@URL{\@ifnextchar\url\test@URL@i\test@URL@ii}
\def\test@URL@i#1\@nil{#1}
\def\test@URL@ii#1\@nil{\url{#1}}
\makeatother

该宏\test@URL会查看下一个 token 是否为\url。因此我们可以看到两种情况

\usebibmacro{archive}{http://www.somesite.com}
\usebibmacro{archive}{\url{http://www.somesite.com}}

情况 1:我们得到

\\\textsc{Archived:} \test@URL http://www.somesite.com\@nil

然后\test@URL没有找到\url,所以它执行

\test@URL@ii http://www.somesite.com\@nil

变成

\url{http://www.somesite.com}

(的论点\test@URL@ii是一切都取决于\@nil)。

情况 2:我们得到

\\\textsc{Archived:} \test@URL \url{http://www.somesite.com}\@nil

然后\test@URL找到\url,所以它执行

\test@URL@i \url{http://www.somesite.com}\@nil

变成

\url{http://www.somesite.com}

(再次强调,的论点\test@URL@i一切都取决于\@nil)。

相关内容