如果包含在条件中,循环宏将失败

如果包含在条件中,循环宏将失败

以下代码是答案的子集 这个问题。答案中提供的代码运行良好,但如果我添加条件,则会失败\IfPackageLoaded。我将此错误作为新问题发布,因为它不一定与原始问题有关。

问题与序列有关,\xpretobibmacro尽管我不知道原因。失败消息如下。

\documentclass{article}

\usepackage{filecontents}
\usepackage{ltxcmds}
\makeatletter
\newcommand{\IfPackageLoaded}[2]{\ltx@ifpackageloaded{#1}{#2}{}}
\makeatother

\usepackage{biblatex}  
\usepackage{xpatch}

\IfPackageLoaded{biblatex}{%

% \boldnames: etoolbox-list of names to typeset bold in \printbibiliography
\newcommand*{\boldnames}{}

\newbibmacro*{name:bold}[2]{%
  \def\do##1{\ifstrequal{#1, #2}{##1}{\bfseries\listbreak}{}}%
  \dolistloop{\boldnames}}

\xpretobibmacro{name:last-first}{\begingroup\usebibmacro{name:bold}{#1}{#2}}{}{}
\xapptobibmacro{name:last-first}{\endgroup}{}{}

%
\DeclareNameAlias{default}{last-first/first-last}

}% \IfPackageLoaded{biblatex}

\addbibresource{publications.bib}

\begin{document}

\begin{filecontents*}{publications.bib}
@Article{Pospiech2010,
  Title                    = {Single-sweep laser writing of 3D-waveguide devices},
  Author                   = {Matthias Pospiech and Moritz Emons and Benjamin V\"{a}ckenstedt and Guido Palmer and Uwe Morgner},
  Journal                  = {Opt. Express},
  Year                     = {2010},
  Number                   = {7},
  Pages                    = {6994--7001},
  Volume                   = {18},
}
\end{filecontents*}

\begin{refsection}%
\nocite{*}
\printbibliography[heading=none, sorting=ynt, resetnumbers=true] %env=numbered+bold, 
\end{refsection}

\end{document}

错误是

! Undefined control sequence.
<argument> \blx@do 
                   {Pospiech2009}\blx@listloop@i 

答案1

当使用xpatch(或中的原始命令etoolbox)修补宏时,建议使用内置诊断,即\tracingpatches“失败”参数。

如果你\tracingpatches在使用之前在序言中添加\IfPackageLoaded,你会得到这样的信息

[debug] tracing \pretocmd on input line 26
[debug] analyzing '\abx@macro@name:last-first'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ control sequence is a macro with parameters
[debug] -- nested patching command and parameters in patch
[debug] -> the patching command seems to be nested in the
[debug]    argument to some other command
[debug] -> the patch text seems to contain # characters
[debug] -> either avoid nesting or use # characters with
[debug]    category code 12 in the patch text
[debug] -> simply doubling the # characters will not work

如果你添加\ddt“fail”参数(或任何未定义的控制序列),TeX 将停止,这意味着补丁失败。消息解释了出错的原因:当补丁出现在另一个命令的参数中时,不能在、或和派生命令#的参数中使用标记,在本例中为。\patchcmd\pretocmd\apptocmdxpatch\IfPackageLoaded

在这种情况下etoolbox建议一种解决方法:使用#类别代码 12:

\IfPackageLoaded{biblatex}{%
  % \boldnames: etoolbox-list of names to typeset bold in \printbibiliography
  \newcommand*{\boldnames}{}
  \newbibmacro*{name:bold}[2]{%
    \def\do##1{\ifstrequal{#1, #2}{##1}{\bfseries\listbreak}{}}%
    \dolistloop{\boldnames}}
  \begingroup\lccode`~=`#\lowercase{\endgroup
    \xpretobibmacro{name:last-first}{\begingroup\usebibmacro{name:bold}{?1}{?2}}{}{}%
  }
  \xapptobibmacro{name:last-first}{\endgroup}{}{}
  %
  \DeclareNameAlias{default}{last-first/first-last}
}

使用此\lowercase技巧是有效的,因为幸运的是,命令参数中的所有字符标记\xpretobibmacro都是小写的。大写字符需要适当的声明,例如

\lccode`A=`A

旁边\lccode`?=`#


顺便说一句,我发现这个\IfPackageLoaded命令的名字不对:据我所知,所有\@if...\If...命令都有“真”和“假”两种情况的参数。也许\DoIfPackageLoaded这个名字更好。

相关内容