考虑一下代码
\documentclass[openany]{book}
\usepackage{tcolorbox}
\usepackage{imakeidx}
\makeindex
\usepackage{idxlayout}
\makeatletter
\def\@wrindex#1#2{%
\imki@wrindexentrysplit {#1}{#2}{\arabic{enumi}}\endgroup \imki@showidxentry
{#1}{#2}\@esphack}
\makeatother
\newtcbox{\purplebox}[1][]{nobeforeafter,
notitle,
colframe=purple!20!black,
colback=purple!50!black,
top=4pt,
left=5pt,
right=5pt,
bottom=2pt,
fontupper=\sffamily\bfseries,
colupper=white,
tcbox raise base,
#1}
\usepackage{enumitem}
\let\olditem\item
\newcommand*{\purpleboxitems}{%
\renewcommand*{\item}[1][]{%
\ifblank{##1}{\olditem}{\olditem[\purplebox{##1}]}%
}%
}
\setlist{
label*={\purplebox{\arabic*}},
before=\purpleboxitems,
after=\let\item\olditem,
}
\begin{document}
\thispagestyle{empty}
\Large
\begin{enumerate}
\item Regular item.\index{First regular item}
\item Regular item.\index{Second regular item}
\item[2*] Special item.\index{Special item}
\item Regular item.\index{Second regular item}
\idxlayout{columns=1}
\printindex
\end{enumerate}
\end{document}
在第一页上产生
其次是索引:
请注意,只要默认标签未作任何修改,索引就会引用正确的项目标签;但是,当在 MWE 中,项目标签(编号)更改为 时2*
,尽管在枚举列表中正确给出,但在索引中引用不正确---给出的是2
而不是2*
。
问题:如何修改上述代码,以便在索引中正确引用此类“特殊项目”?
谢谢。
答案1
makeindex
按键和页面对索引条目进行排序,因此它(似乎)要求每个页面都采用一种且仅一种“数字”形式(数字、阿拉伯和罗马)。
您的示例中的2*
“数字”形式不是有效的,因此恐怕您必须进行页面封装(\index{<key>|<cmd>}), manually or automatically if you patch the
\index` 内部)。
手动页面封装示例:
% define
\newcommand{\idxStarred}[1]{#1*}
% then use
\item[2*] Special item.\index{Special item|idxStarred}
注意这并不能解决所有问题。例如,排序时它无法使所有未加星号的索引条目小于加星号的索引条目。
更新:这次新尝试将“特殊页面”拆分为页面和页面辅助部分(使用l3regex
),然后自动插入页面封装。因此
% input
\item[2*] Special item\index{special item}
% i) will generate, in `.idx` file
\indexentry{Special item|myindexPrintPage{*}}{2}
% ii) will become, in `.ind` file, after running `makeindex`
\item Special item, \myindexPrintPage{*}{2}
% iii) will finally typeset as, in `.pdf` file
Special item, 2*
\documentclass[openany]{book}
\usepackage{enumitem}
\usepackage{tcolorbox}
\usepackage{imakeidx}
\usepackage{idxlayout}
\makeindex
\ExplSyntaxOn
\tl_new:N \l_myindex_page_tl % beginning digits
\tl_new:N \l_myindex_page_aux_tl % anything left
\regex_const:Nn \c_begining_digits_regex { ^(\d+) }
\msg_new:nnn {myindex} {wrong-page-pattern}
{Wrong page pattern ``\tl_to_str:n{#1}''}
% split special page into page_tl and page_aux_tl
% e.g.
% input: special page == "2*"
% output: page_tl == "2", page_aux_tl == "*"
\cs_new:Nn \myindex_split_page:n
{
\regex_split:NnNTF \c_begining_digits_regex {#1} \l_tmpa_seq
{
% now the seq is "<empty>, page_tl, page_aux_tl"
\seq_pop_right:NN \l_tmpa_seq \l_myindex_page_aux_tl
\seq_pop_right:NN \l_tmpa_seq \l_myindex_page_tl
}
{ \msg_error:nnn {myindex} {wrong-page-pattern} {#1} }
}
\cs_generate_variant:Nn \myindex_split_page:n {V}
\makeatletter
\cs_set_eq:NN \myindexPrintPage \@swaptwoargs
\def\@wrindex#1#2{%
\ifdefined\@currentitem
\myindex_split_page:V \@currentitem
\imki@wrindexentrysplit{#1}
{#2|myindexPrintPage{\l_myindex_page_aux_tl}}
{\l_myindex_page_tl}%
\endgroup
\imki@showidxentry{#1}{#2}%
\else
\imki@wrindexentrysplit{#1}{#2}{\arabic{enumi}}%
\endgroup
\imki@showidxentry{#1}{#2}%
\fi
\@esphack
}
\makeatother
\ExplSyntaxOff
\makeatletter
\let\olditem\item
\newcommand*{\purpleboxitems}{%
\renewcommand*{\item}[1][]{%
\ifblank{##1}
{\let\@currentitem\@undefined\olditem}
{\def\@currentitem{##1}\olditem[\purplebox{##1}]}%
}%
}
\makeatother
\newtcbox{\purplebox}[1][]{nobeforeafter,
notitle,
colframe=purple!20!black,
colback=purple!50!black,
top=4pt,
left=5pt,
right=5pt,
bottom=2pt,
fontupper=\sffamily\bfseries,
colupper=white,
tcbox raise base,
#1}
\setlist{
label*={\purplebox{\arabic*}},
before=\purpleboxitems,
after=\let\item\olditem,
}
\begin{document}
\thispagestyle{empty}
\Large
\begin{enumerate}
\item Regular item.\index{First regular item}
\item Regular item.\index{Second regular item}
\item[2*] Special item.\index{Special item}
\item[2+] Another special item.\index{Special item}
\item Regular item.\index{Second regular item}
\item[3$\neq$] Third special item.\index{Special item}
\end{enumerate}
\idxlayout{columns=1}
\printindex
\end{document}