![索引和 l3regex 的奇怪行为](https://linux22.com/image/307110/%E7%B4%A2%E5%BC%95%E5%92%8C%20l3regex%20%E7%9A%84%E5%A5%87%E6%80%AA%E8%A1%8C%E4%B8%BA.png)
index
我正在试验 LaTeX3 的功能,在和 的组合中出现了奇怪的行为。我尝试用感叹号符号l3regex
替换所有出现的,以便列表中的条目在索引中获得子条目。:<space>
\documentclass[]{scrbook}
\usepackage{index}
\usepackage{xparse}
\usepackage{l3regex}
\makeindex
\ExplSyntaxOn
\tl_new:N \l_demo_tl
\cs_new:Npn \demo #1 {
\tl_set:Nn \l_demo_tl {#1}
\regex_replace_all:nnN { :\h } {!} \l_demo_tl
\tl_use:N \l_demo_tl
}
\ExplSyntaxOff
\NewDocumentCommand{\prozessIndex}{m}{\index{\demo{#1}}}
\NewDocumentCommand{\prozessIndexList}{>{\SplitList{,}}m}{%
\ProcessList{#1}{\prozessIndex}%
}
\begin{document}
Here some Text
\prozessIndexList{Hello,Hello: World, Muh,Muh!Kuh}
\printindex
\end{document}
但结果是
Hello!World ,1
Hello , 1
Muh
Kuh , 1
Muh , 1
但它应该是
Hello , 1
World , 1
Muh
Kuh , 1
Muh , 1
还有其他的路可走吗?
答案1
查看文件.idx
,你会看到
\indexentry {\demo {Hello}}{1}
\indexentry {\demo {Hello: World}}{1}
\indexentry {\demo {Muh}}{1}
\indexentry {\demo {Muh!Kuh}}{1}
您不想让 makeindex 看到\demo
而是希望看到运行 demo 的结果,因此:
\documentclass[]{scrbook}
\usepackage{index}
\usepackage{xparse}
\usepackage{l3regex}
\makeindex
\ExplSyntaxOn
\tl_new:N \l_demo_tl
\cs_new:Npn \demo #1 {
\tl_set:Nn \l_demo_tl {#1}
\regex_replace_all:nnN { :\h } {!} \l_demo_tl
\tl_use:N \l_demo_tl
}
\ExplSyntaxOff
\NewDocumentCommand{\prozessIndex}{m}{\demo{\index{#1}}}
\NewDocumentCommand{\prozessIndexList}{>{\SplitList{,}}m}{%
\ProcessList{#1}{\prozessIndex}%
}
\begin{document}
Here some Text
\prozessIndexList{Hello,Hello: World, Muh,Muh!Kuh}
\printindex
\end{document}
现在 idx 看起来像
\indexentry {Hello}{1}
\indexentry {Hello!World}{1}
\indexentry {Muh}{1}
\indexentry {Muh!Kuh}{1}
答案2
如果用 替换index
,makeidx
您会收到几个关于未定义控制序列的错误\h
,这暗示着出现了问题;但重点是该.idx
文件最终包含
\indexentry{\tl_set:Nn {Hello}\regex_replace_all:nnN {:}{!}}{1}
\indexentry{\tl_set:Nn {Hello: World}\regex_replace_all:nnN {:}{!}}{1}
\indexentry{\tl_set:Nn {Muh}\regex_replace_all:nnN {:}{!}}{1}
\indexentry{\tl_set:Nn {Muh!Kuh}\regex_replace_all:nnN {:}{!}}{1}
这绝对不是你想要的。有了这个\index
包,你会得到
\indexentry{\demo {Hello}
等等,所以问题是一样的。
你必须进行更换前把单词喂给\index
。而正常的xparse
设施是不够的。
\documentclass[]{scrbook}
\usepackage{makeidx}
\usepackage{xparse}
\usepackage{l3regex}
\makeindex
\ExplSyntaxOn
\NewDocumentCommand{\indexlist}{m}
{% pass control to an internal function
\landarzar_indexlist:n { #1 }
}
% two variables
\tl_new:N \l_landarzar_temp_tl
\seq_new:N \l_landarzar_list_seq
% translate `\index` into an internal function
\cs_set_eq:NN \landarzar_index:n \index
% define a variant that uses a value, instead of an explicit argument
\cs_generate_variant:Nn \landarzar_index:n { V }
\cs_new_protected:Npn \landarzar_indexlist:n #1
{
% split the input into pieces
\seq_set_split:Nnn \l_landarzar_list_seq { , } { #1 }
% process each item in turn
\seq_map_inline:Nn \l_landarzar_list_seq
{
% pass the item through the regex replacement
\tl_set:Nn \l_landarzar_temp_tl { ##1 }
\regex_replace_all:nnN { :\s } { ! } \l_landarzar_temp_tl
% emit the \index command
\landarzar_index:V \l_landarzar_temp_tl
}
}
\ExplSyntaxOff
\begin{document}
Here some Text
\indexlist{Hello,Hello: World, Muh,Muh!Kuh}
\printindex
\end{document}
现在.idx
文件内容如下
\indexentry{Hello}{1}
\indexentry{Hello!World}{1}
\indexentry{Muh}{1}
\indexentry{Muh!Kuh}{1}
解释
使用序列将参数拆分为组件(这基本上就是它的\ProcessList
作用)。然后传递每个项目并调用\regex_replace_all:nnN
正确的命令,使用\index
价值令牌列表。
笔记
使用makeidx
或imakeidx
宏\index
对其输入执行扩展步骤,而这在包中不会发生index
。
允许多个索引的变体代码(我使用imakeidx
,但也可以类似地使用index
)。代码非常相似,唯一相关的区别是如何处理可选参数。
\documentclass[]{scrbook}
\usepackage{xparse}
\usepackage{l3regex}
\usepackage{imakeidx}
\makeindex
\makeindex[name=landarzarx]
\ExplSyntaxOn
\NewDocumentCommand{\indexlist}{O{}m}
{
\landarzar_indexlist:nn { #1 } { #2 }
}
\tl_new:N \l_landarzar_temp_tl
\seq_new:N \l_landarzar_list_seq
\cs_new_protected:Npn \landarzar_index:n #1
{
\index{#1}
}
\cs_new_protected:Npn \landarzar_index:nn #1 #2
{
\index[#1]{#2}
}
\cs_generate_variant:Nn \landarzar_index:n { V }
\cs_generate_variant:Nn \landarzar_index:nn { nV }
\cs_new_protected:Npn \landarzar_indexlist:nn #1 #2
{
\seq_set_split:Nnn \l_landarzar_list_seq { , } { #2 }
\seq_map_inline:Nn \l_landarzar_list_seq
{
\tl_set:Nn \l_landarzar_temp_tl { ##1 }
\regex_replace_all:nnN { :\s } { ! } \l_landarzar_temp_tl
\tl_if_empty:nTF { #1 }
{ \landarzar_index:V \l_landarzar_temp_tl } % no optional argument
{ \landarzar_index:nV { #1 } \l_landarzar_temp_tl } % optional argument
}
}
\ExplSyntaxOff
\begin{document}
Here some Text
\indexlist{Hello,Hello: World, Muh,Muh!Kuh}
\indexlist[landarzarx]{Hello,Hello: World, Muh,Muh!Kuh}
\printindex
\printindex[landarzarx]
\end{document}