我正在写一篇相当长的文档,我想只在第一次出现时突出显示某些名称,但每次都将它们添加到索引中。换句话说,我想要:
\important{John Smith}
行为如下:
\textbf{John Smith}\index{John Smith}
第一次出现。像这样:
John Smith \index{John Smith}
任何后续时间。当然我可以创建命令,但是现在文本非常流畅,我宁愿让这个自动化。
答案1
这可以通过序列列表来实现,其中每个序列\important{...}
列表检查单词(表达式)是否已添加到列表中,如果没有,则突出显示,否则\index{...}
使用。
获得列表和检查工作的最简单方法是使用expl3
即将推出的 LaTeX 3 格式的新功能 - 但它已经可以与任何现代 TeX 发行版一起使用。
一些注意事项:
显示和索引值的使用\index{#1}
并不健康,需要进行一些改进(例如\important{foo!bar}
不太好)
\documentclass{article}
\usepackage{makeidx}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_hernan_seq
\NewDocumentCommand{\important}{m}{
\seq_if_in:NnTF{\l_hernan_seq}{#1}{
#1\index{#1}
}{
\seq_put_left:Nn{\l_hernan_seq}{#1}
\textbf{#1}
\index{#1}
}
}
\ExplSyntaxOff
\makeindex
\begin{document}
Here is some \important{expression} which isn't highlighted again here \important{expression}
And another \important{word}, not highlighted in here: \important{word}
\printindex
\end{document}
编辑
\documentclass{article}
\usepackage{imakeidx}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_hernan_seq
\NewDocumentCommand{\important}{m}{
\seq_if_in:NnTF{\l_hernan_seq}{#1}{
#1\index{#1}
}{
\seq_put_left:Nn{\l_hernan_seq}{#1}
\textbf{#1}
\index{#1}
}
}
\NewDocumentCommand{\getimportantwordslist}{+O{\par}}{
\seq_use:Nn{\l_hernan_seq}{#1}
}
\ExplSyntaxOff
\NewDocumentCommand{\PrintHighlighted}{+m}{%
Here is the list of important words:
\getimportantwordslist
}
\makeindex
\begin{document}
\important{Here} starts the stuff, but \important{Here} it's not highlighted!
Here is some \important{expression} which isn't highlighted again here: \important{expression}
And another \important{word}, not highlighted in here: \important{word}
\PrintHighlighted
\end{document}
答案2
您可以使用类似包glossaries
并将索引术语添加为词汇表项。词汇表项在文本中首次出现时有特定的样式。您可以根据需要设置该样式。并且您可以使用词汇表包生成索引列表。唯一的缺点是,您需要单独定义所有词汇表项,最好在词汇表文件中定义。这并不难,因为如果您有一个未定义的条目,您将收到一条错误消息,然后您可以将该项目添加到词汇表中。
答案3
我采纳了 Christian 的回答,并尝试在复杂的索引情况下做出一些工作。我能想到的最复杂的情况是这样的
A!b!C@D|E
在这种情况下,需要以粗体打印的是 C,因此我们必须进行一些操作。
一种解决方案可能是使用分隔参数,但我决定使用该 \seq_set_split:
命令:首先我使用|
as 分隔符创建一个序列,然后我只取该序列的第一个元素,即除|...
部分之外的所有内容。
然后我创建另一个带有@
分隔符的序列,然后又创建另一个带有!
分隔符的序列。此序列的最后一个元素是条目,存储在\l_hernan_entry_tl
标记列表中。现在您可以按照 Christian 的建议去做。
\documentclass{article}
\usepackage{imakeidx}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \l_hernan_seq
\tl_new:N \l_hernan_first_split_tl % for storing the entry without "|see..." part
\tl_new:N \l_hernan_second_split_tl % for storing the entry without "@..." part
\tl_new:N \l_hernan_entry_tl % for storing the entry
\seq_new:N \l_hernan_vertical_bar_seq
\seq_new:N \l_hernan_at_seq
\seq_new:N \l_hernan_entries_seq
\NewDocumentCommand{\important}{m}
{
\seq_set_split:Nnn \l_hernan_vertical_bar_seq {|} {#1}
\seq_get_left:NN \l_hernan_vertical_bar_seq \l_hernan_first_split_tl
%
\seq_set_split:NnV \l_hernan_at_seq {@} \l_hernan_first_split_tl
\seq_get_left:NN \l_hernan_at_seq \l_hernan_second_split_tl
%
\seq_set_split:NnV \l_hernan_entries_seq {!} \l_hernan_second_split_tl
\seq_get_right:NN \l_hernan_entries_seq \l_hernan_entry_tl
%
\seq_if_in:NVTF\l_hernan_seq \l_hernan_entry_tl
{\l_hernan_entry_tl \index{#1}} %true
{\seq_put_left:NV \l_hernan_seq \l_hernan_entry_tl
\textbf{\l_hernan_entry_tl}\index{#1}} %false
%\seq_show:N \l_hernan_seq
}
\NewDocumentCommand{\getimportantwordslist}{+O{\par}}{
\seq_use:Nn{\l_hernan_seq}{#1}
}
\ExplSyntaxOff
\NewDocumentCommand{\PrintHighlighted}{+m}{%
Here is the list of important words:
\getimportantwordslist
}
\makeindex
\begin{document}
The most complex situation that I can imagine is \important{Mainentry!subentry!realentry@myentry|see{other}} for indexing the \important{realentry} word as \important{myentry}.
\important{Here} starts the stuff, but \important{Here} it's not highlighted!
Here is some \important{expression} which isn't highlighted again here: \important{expression}
And another \important{word}, not highlighted in here: \important{word}
\bigskip
\PrintHighlighted
\printindex
\end{document}
如果您发现一些错误,请告诉我。