索引和 l3regex 的奇怪行为

索引和 l3regex 的奇怪行为

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

如果用 替换indexmakeidx您会收到几个关于未定义控制序列的错误\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价值令牌列表。

笔记

使用makeidximakeidx\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}

相关内容