所以我一直在写一本书,我曾经用它来xparse
创建一些命令和环境。现在,当事情快要完成时,我意识到有一个索引会很棒!我创建的一个环境接受一个参数,并给出一个带有参数的小框作为标题。所有这些框都使用表单作为foo: bar
标题,我想索引bar
。
我意识到xstring
可以帮助我,并测试了\index{\StrBehind{foo: bar}{:}}
哪些工作没有麻烦(见MWE),但是当我声明命令
\DeclareDocumentCommand \cutindex {m}{\index{\StrBehind{#1}{:}}}
我得到了错误
! Argument of \reserved@a has an extra }.
---Mumbo which is better to read from MWE---
! Paragraph ended before \reserved@a was complete.
我也尝试过使用临时命令来保存字符串,但这也不起作用。
\newcommand{\tempor}{}
\DeclareDocumentCommand \cutindex {m}{
\renewcommand{\tempor}{\StrBehind{#1}{:}}
\index{\tempor}
}
我得出的结论是,\index{\command}
在普通文本中确实有效,但在\DeclareDOcumentCommand
(或\newcommand
) 中无效。是否有可能以某种方式绕过此限制?
梅威瑟:
\documentclass{article}
\usepackage{xstring}
\usepackage{makeidx}
\usepackage{xparse}
\DeclareDocumentCommand \cutindex {m}{\index{\StrBehind{#1}{:}}}
\makeindex
\begin{document}
This works! \index{\StrBehind{Foo: Bar}{:}}
This does not work! \cutindex{Bar: Foo}
\printindex
\end{document}
答案1
Joseph Wright 的诊断是正确的:您无法执行诸如\StrBehind
在\index
条目中的命令。
这是一个不同的解决方案,使用l3regex
:
\documentclass{article}
\usepackage{xparse,l3regex}
\usepackage{imakeidx}
\makeindex
\ExplSyntaxOn
\NewDocumentCommand{\cutindex}{m}
{
\robert_cutindex:n { #1 }
}
\tl_new:N \l__robert_entry_tl
\cs_new_protected:Npn \robert_cutindex:n #1
{
\tl_set:Nn \l__robert_entry_tl { #1 }
\regex_replace_once:nnN { .*? \: \s* } { } \l__robert_entry_tl
\index{ \l__robert_entry_tl }
}
\ExplSyntaxOff
\begin{document}
Here's a standard entry: \index{Foo}
This works! \cutindex{Bar: Foo}
And this also! \cutindex{Bar:Foo}
\printindex
\end{document}
请注意,冒号后的空格会被忽略,因此可以使用也可以不使用。搜索正则表达式会查找到第一个冒号(后跟零个或多个空格)之前的所有字符;替换操作就是将它们丢弃。
答案2
您可能需要查看.idx
文件以查看这里的“工作”是否与您期望的完全一致:您会看到
\indexentry{\StrBehind{Foo: Bar}{:}}{1}
\indexentry{\let \reserved@d =*\def \par }{1}
原因是它\index
逐字读取它的参数。当它不在另一个命令中时,这很好,但如果你已经获取了该参数,它就会失败。如果你已经标记化输入,也就是你使用
\DeclareDocumentCommand \cutindex {m}{\index{\StrBehind{#1}{:}}}
就像\StrBehind
一个命令,而不是一个字符串。
还有一个问题是\StrBehind
无法扩展,这意味着即使没有业务,\index
您也不能简单地将其粘贴到您想要文本的地方。但是,您可以使用可选参数将结果存储在宏中,然后在正确的位置扩展它(它是一个字符串,所以这是安全的)。
\DeclareDocumentCommand \cutindex {m}{%
\StrBehind{#1}{:}[\tempa]%
\index{\tempa}%
}
(您会注意到我没有费心去扩展,\tempa
因为我知道\index
在写入.idx
文件时会这样做。)