我正在尝试生成一本书中使用的人名索引。
首次出现时,会使用人物的全名(即名字和姓氏以及可能的附加说明)来介绍该人物,之后在文中只会使用该人的姓名。
我打算使用老旧的 makeindex 来生成索引,因为不需要其他索引。因此我编写了宏,一个用于人的初次出现,一个用于以后的所有出现。初次出现宏使用姓名和姓氏作为强制参数,第二个宏仅使用姓名作为强制参数。
\index
我认为,通过-command 使用@
类似这样的方式写入姓名会很聪明\index{#2@#2}
(假设,人员姓名始终存储在 #2 中,其姓氏存储在 #3 中)。因此,对于初始外观,索引将如下所示:
\index{#2@#2, #3}
这是进一步露面的呼吁:
\index{#2}
不幸的是,Makeindex 不会将它们识别为唯一名称。即使我将第二个宏更改为使用 also @
:
\index{#2@#2}
将显示为同名的第二个条目。
哪里出了问题?我必须改变什么?
以下是 MWE:
\documentclass[a4paper]{scrartcl}
\usepackage[main=english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\usepackage{ifthen}
%% Definition of macros
%% Initpers is used, when the person is first mentioned. It takes 4
%% arguments:
%% #1: Output in the text (optional)
%% #2: Name (mandatory)
%% #3: Surname (mandatory)
%% #4: Description (mandatory but most of the time empty)
%%
\newcommand{\initpers}[4][]{%
% output the name and surname into the text. If the optional
% argument #1 is given, use this, else use the mandatory arguments
% #2 and #3
\ifthenelse{\equal{#1}{}}{
{#3 #2}}{%
#1}%
% Now, insert Name, Surname and the Description (if given) into the index.
\ifthenelse{\equal{#4}{}}{%
\index{#2@#2, #3}}{%
\index{#2@#2, #3 (#4)}}%
}%
%% This macro shall be used, whenever a person, which was already
%% introduced, shall be mentioned again. In this case, only the name
%% is used.
\newcommand{\pers}[1]{%
% output the name into the text, enter it into the index.
% #1\index{#1}
#1\index{#1@#1}%
}%
% generate the index
\makeindex
\begin{document}
This is some text, in which I will reflect on the book ``The two
cultures'' by \initpers{Snow}{Charles Percy}{}. This book \dots
%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\newpage
This was also mentioned by \pers{Snow} as described earlier.
\printindex
\end{document}
这是令人遗憾的结果,因为尽管这是一个人并且应该列为斯诺,查尔斯·珀西,1,2,但它却包含了斯诺先生的两个条目:
答案1
我的解决方案将名称和潜在描述存储到expl3
属性列表中,并处理索引格式。如果没有描述,则提取普通格式,否则在\index
- 调用中添加描述。
这样,就Index
被“压缩”了。
我还曾经\NewDocumentCommand
在 的末尾提供一个可选参数\InitPerson
。
宏\displayname
、\descriptionformat
和\nodescriptionformat
只是为了防止吞噬\ExplSyntaxOn...\ExplSyntaxOff
制度中的空白的包装器。
\documentclass[a4paper]{scrartcl}
\usepackage[main=english]{babel}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{makeidx}
\usepackage{ifthen}
\usepackage{xparse}
%% Definition of macros
%% Initpers is used, when the person is first mentioned. It takes 4
%% arguments:
%% #1: Output in the text (optional)
%% #2: Name (mandatory)
%% #3: Surname (mandatory)
%% #4: Description (mandatory but most of the time empty)
%%
\newcommand{\initpersold}[4][]{%
% output the name and surname into the text. If the optional
% argument #1 is given, use this, else use the mandatory arguments
% #2 and #3
\ifthenelse{\equal{#1}{}}{
{#3 #2}}{%
#1}%
% Now, insert Name, Surname and the Description (if given) into the index.
\ifthenelse{\equal{#4}{}}{%
\index{#2@#2, #3}}{%
\index{#2@#2, #3 (#4)}}%
}%
%% This macro shall be used, whenever a person, which was already
%% introduced, shall be mentioned again. In this case, only the name
%% is used.
\newcommand{\persold}[1]{%
% output the name into the text, enter it into the index.
% #1\index{#1}
#1\index{#1@#1}%
}%
\newcommand{\displayname}[2]{%
#1 #2%
}
\newcommand{\descriptionformat}[3]{%
#1, #2 (#3)%
}
\newcommand{\nodescriptionformat}[2]{%
#1, #2%
}
\ExplSyntaxOn
\newcommand{\propextractname}[1]{%
\prop_item:Nn \g_jan_person_prop {#1}%
}
\newcommand{\propextractdescription}[1]{%
\displayname{\prop_item:Nn \g_jan_person_prop {#1}}{(\prop_item:Nn \g_jan_person_prop {#1-description})}%
}
\prop_new:N \g_jan_person_prop
\seq_new:N \g_jan_personused_seq
\NewDocumentCommand{\InitPerson}{o+m+m+o}{%
\IfNoValueTF{#1}{%
\displayname{#3}{#2}%
}{%
#1%
}%
\IfValueTF{#4}{%
\prop_gput:Nnn \g_jan_person_prop {#2-description} {#4}
\index{\descriptionformat{#2}{#3}{#4}}
}{
\index{\nodescriptionformat{#2}{#3}}
}
\prop_gput:Nnn \g_jan_person_prop {#2} {#3}
}
\NewDocumentCommand{\Person}{+m}{%
#1%
\prop_if_in:NnTF \g_jan_person_prop {#1}
{
\prop_if_in:NnTF \g_jan_person_prop {#1-description}
{
\typeout{Yes: #1}
\index{#1,~\propextractdescription{#1}}
}{
\index{#1,~\propextractname{#1}}
}
}{
\index{#1}
}
}
\ExplSyntaxOff
\makeindex
\begin{document}
This is some text, in which I will reflect on the book ``The two
cultures'' by \InitPerson{Snow}{Charles Percy}. This book \dots
\InitPerson{Vader}{Darth}[Father of Luke Skywalker]
%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\clearpage
This was also mentioned by \Person{Snow} as described earlier.
The arch villain \Person{Vader}
\clearpage
\Person{Snow}
\printindex
\end{document}
答案2
之前的部分@
仅用于排序,但\index{a@aa}
和\index{a@aabb}
是不同的項目。
Christian Hupfer 提出的代码可以简化。您也许应该重新考虑将第一个可选参数提供给时会发生什么\initpers
。
\documentclass[a4paper]{scrartcl}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[main=english]{babel}
\usepackage{makeidx} % or imakeidx
\usepackage{xparse}
\ExplSyntaxOn
%% Definition of macros
%% Initpers is used, when the person is first mentioned. It takes 4
%% arguments:
%% #1: Output in the text (optional)
%% #2: Family name (mandatory)
%% #3: Given name (mandatory)
%% #4: Description (optional)
%%
\NewDocumentCommand{\initpers}{ommo}
{
% output the name and surname into the text. If the optional
% argument #1 is given, use this, else use the mandatory arguments
% #2 and #3
\IfNoValueTF { #1 }
{
% no optional argument, print given name and family name
#3~#2
}
{
% optional argument, print just it
#1
}
% store the data
\prop_gput:Nnn \g_jan_persons_prop { #2 familyname } { #2 }
\prop_gput:Nnn \g_jan_persons_prop { #2 givenname } { #3 }
\IfValueT { #4 }
{
\prop_gput:Nnn \g_jan_persons_prop { #2 description } { #4 }
}
\index{#2@\usename{#2}}
}
\NewDocumentCommand{\pers}{m}
{
% output the name into the text, enter it into the index.
% #1\index{#1}
#1\index{#1@\usename{#1}}
}
\NewDocumentCommand{\usename}{m}
{
\prop_item:Nn \g_jan_persons_prop { #1 familyname }
,\c_space_tl
\prop_item:Nn \g_jan_persons_prop { #1 givenname }
\prop_if_in:NnTF \g_jan_persons_prop { #1 description }
{
\c_space_tl (\prop_item:Nn \g_jan_persons_prop { #1 description })
}
}
\prop_new:N \g_jan_persons_prop
\ExplSyntaxOff
% generate the index
\makeindex
\begin{document}
This is some text, in which I will reflect on the book ``The two
cultures'' by \initpers{Snow}{Charles Percy}. This book \dots
We also talk about \initpers{Vader}{Darth}[Father of Luke Skywalker]
and \initpers[Stendhal]{Beyle}{Henri}
%% For the sake of this example, lets assume, we mention Mr. Snow
%% later on
\clearpage
This was also mentioned by \pers{Snow} as described earlier
And we also have \pers{Vader} and \pers{Beyle}.
\printindex
\end{document}