我正在使用定制的 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
)。